diff --git a/.sbtopts b/.sbtopts new file mode 100644 index 0000000..6913385 --- /dev/null +++ b/.sbtopts @@ -0,0 +1 @@ +-mem 2048 -J-XX:+UseG1GC diff --git a/.sbtopts b/.sbtopts new file mode 100644 index 0000000..6913385 --- /dev/null +++ b/.sbtopts @@ -0,0 +1 @@ +-mem 2048 -J-XX:+UseG1GC diff --git a/bom.sc b/bom.sc deleted file mode 100644 index 636a511..0000000 --- a/bom.sc +++ /dev/null @@ -1,234 +0,0 @@ -import mill._, scalalib._ - -object IWMaterials { - - object Versions { - val akka = "2.6.16" - val akkaHttp = "10.2.4" - val cats = "2.7.0" - val elastic4s = "7.12.2" - val http4s = "0.23.10" - val http4sPac4J = "4.0.0" - val laminar = "0.14.2" - val laminext = laminar - val logbackClassic = "1.2.10" - val pac4j = "5.2.0" - val play = "2.8.8" - val playJson = "2.9.2" - val refined = "0.9.29" - val scalaTest = "3.2.9" - val slf4j = "1.7.36" - val slick = "3.3.3" - val sttpClient = "3.5.0" - val tapir = "0.20.1" - val urlDsl = "0.4.0" - val waypoint = "0.5.0" - val zio = "2.0.0-RC2" - val zioConfig = "3.0.0-RC2" - val zioInteropCats = "3.3.0-RC2" - val zioJson = "0.3.0-RC3" - val zioLogging = "2.0.0-RC5" - val zioPrelude = "1.0.0-RC10" - val zioZMX = "0.0.11" - } - - object Deps extends AkkaLibs with SlickLibs { - import IWMaterials.{Versions => V} - - val zioOrg = "dev.zio" - - def zioLib(name: String, version: String): Dep = - ivy"$zioOrg::zio-$name::$version" - - lazy val zio: Dep = ivy"$zioOrg::zio:${V.zio}" - - lazy val zioTest: Dep = zioLib("test", V.zio) - lazy val zioTestSbt: Dep = zioLib("test-sbt", V.zio) - - lazy val zioConfig: Dep = zioLib("config", V.zioConfig) - lazy val zioConfigTypesafe: Dep = - zioLib("config-typesafe", V.zioConfig) - lazy val zioConfigMagnolia: Dep = - zioLib("config-magnolia", V.zioConfig) - - lazy val zioJson: Dep = zioLib("json", V.zioJson) - lazy val zioLogging: Dep = zioLib("logging", V.zioLogging) - lazy val zioLoggingSlf4j: Dep = - zioLib("logging-slf4j", V.zioLogging) - lazy val zioPrelude: Dep = zioLib("prelude", V.zioPrelude) - lazy val zioStreams: Dep = zioLib("streams", V.zio) - lazy val zioZMX: Dep = zioLib("zmx", V.zioZMX) - lazy val zioInteropCats: Dep = - zioLib("interop-cats", V.zioInteropCats) - - lazy val catsCore: Dep = ivy"org.typelevel::cats-core::${V.cats}" - - lazy val refined: Dep = ivy"eu.timepit::refined::${V.refined}" - - /* What is the equivalent? ZIOModule with prepared test config? - def useZIO(testConf: Configuration*): Agg[Dep] = Agg( - zio, - zioTest, - zioTestSbt, - testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework") - ) - */ - - /* - def useZIOAll(testConf: Configuration*): Seq[Def.Setting[_]] = - useZIO(testConf: _*) ++ Seq( - zioStreams, - zioConfig, - zioConfigTypesafe, - zioConfigMagnolia, - zioJson, - zioZMX, - zioLogging, - zioPrelude - ) - */ - - private val tapirOrg = "com.softwaremill.sttp.tapir" - def tapirLib(name: String): Dep = - ivy"${tapirOrg}::tapir-$name::${V.tapir}" - - lazy val tapirCore: Dep = tapirLib("core") - lazy val tapirZIO: Dep = tapirLib("zio") - lazy val tapirZIOJson: Dep = tapirLib("json-zio") - lazy val tapirSttpClient: Dep = tapirLib("sttp-client") - lazy val tapirCats: Dep = tapirLib("cats") - lazy val tapirZIOHttp4sServer: Dep = tapirLib("zio-http4s-server") - - val sttpClientOrg = "com.softwaremill.sttp.client3" - def sttpClientLib(name: String): Dep = - 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}" - - lazy val http4sPac4J: Dep = - ivy"org.pac4j::http4s-pac4j:${V.http4sPac4J}" - lazy val pac4jOIDC: Dep = - ivy"org.pac4j:pac4j-oidc:${V.pac4j}" - - lazy val scalaTest: Dep = - ivy"org.scalatest::scalatest:${V.scalaTest}" - lazy val scalaTestPlusScalacheck: Dep = - ivy"org.scalatestplus::scalacheck-1-15:3.2.9.0" - lazy val playScalaTest: Dep = - ivy"org.scalatestplus.play::scalatestplus-play:5.1.0" - - private val playOrg = "com.typesafe.play" - lazy val playMailer: Dep = ivy"${playOrg}::play-mailer:8.0.1" - lazy val playServer: Dep = ivy"${playOrg}::play-server:${V.play}" - lazy val playAkkaServer: Dep = - ivy"${playOrg}::play-akka-http-server:${V.play}" - lazy val play: Dep = ivy"${playOrg}::play:${V.play}" - lazy val playAhcWs: Dep = ivy"${playOrg}::play-ahc-ws:${V.play}" - lazy val playJson: Dep = ivy"${playOrg}::play-json:${V.playJson}" - - private val elastic4sOrg = "com.sksamuel.elastic4s" - lazy val useElastic4S: Agg[Dep] = Agg( - ivy"${elastic4sOrg}::elastic4s-core:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-client-akka:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-http-streams:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-json-play:${V.elastic4s}" - ) - - lazy val laminar: Dep = ivy"com.raquo::laminar::${V.laminar}" - - private def laminext(name: String): Dep = - ivy"io.laminext::$name::${V.laminar}" - - lazy val laminextCore: Dep = laminext("core") - lazy val laminextTailwind: Dep = laminext("tailwind") - lazy val laminextFetch: Dep = laminext("fetch") - lazy val laminextValidationCore: Dep = laminext("validation-core") - lazy val laminextUI: Dep = laminext("ui") - - lazy val waypoint: Dep = - ivy"com.raquo::waypoint::${V.waypoint}" - - lazy val urlDsl: Dep = - ivy"be.doeraene::url-dsl::${V.urlDsl}" - - lazy val scalaJavaTime: Dep = - ivy"io.github.cquiroz::scala-java-time::2.3.0" - - lazy val scalaJavaLocales: Dep = - ivy"io.github.cquiroz::scala-java-locales::1.2.1" - - lazy val logbackClassic: Dep = - ivy"ch.qos.logback:logback-classic:${V.logbackClassic}" - } - - trait AkkaLibs { - - self: SlickLibs => - - object akka { - val V = Versions.akka - val tOrg = "com.typesafe.akka" - val lOrg = "com.lightbend.akka" - - def akkaMod(name: String): Dep = - ivy"$tOrg::akka-$name:$V" - - lazy val actor: Dep = akkaMod("actor") - lazy val actorTyped: Dep = akkaMod("actor-typed") - lazy val stream: Dep = akkaMod("stream") - lazy val persistence: Dep = akkaMod("persistence-typed") - lazy val persistenceQuery: Dep = akkaMod("persistence-query") - lazy val persistenceJdbc: Dep = - ivy"$lOrg::akka-persistence-jdbc:5.0.4" - val persistenceTestKit: Dep = ivy"$tOrg::akka-persistence-testkit:$V" - - object http { - val V = Versions.akkaHttp - - lazy val http: Dep = ivy"$tOrg::akka-http:$V" - lazy val sprayJson: Dep = ivy"$tOrg::akka-http-spray-json:$V" - - } - - object projection { - val V = "1.2.2" - - lazy val core: Dep = - ivy"$lOrg::akka-projection-core:$V" - lazy val eventsourced: Dep = - ivy"$lOrg::akka-projection-eventsourced:$V" - lazy val slick: Dep = - ivy"$lOrg::akka-projection-slick:$V" - lazy val jdbc: Dep = - ivy"$lOrg::akka-projection-jdbc:$V" - } - - object profiles { - // TODO: deal with cross-version for Scala3 (for3Use2_13) - lazy val eventsourcedJdbcProjection: Agg[Dep] = Agg( - persistenceQuery, - projection.core, - projection.eventsourced, - projection.slick, - persistenceJdbc - ) ++ slick.default - } - } - } - - trait SlickLibs { - object slick { - val V = IWMaterials.Versions.slick - val org = "com.typesafe.slick" - - lazy val slick: Dep = ivy"$org::slick:$V" - lazy val hikaricp: Dep = ivy"$org::slick-hikaricp:$V" - lazy val default: Agg[Dep] = Agg(slick, hikaricp) - } - } - -} diff --git a/.sbtopts b/.sbtopts new file mode 100644 index 0000000..6913385 --- /dev/null +++ b/.sbtopts @@ -0,0 +1 @@ +-mem 2048 -J-XX:+UseG1GC diff --git a/bom.sc b/bom.sc deleted file mode 100644 index 636a511..0000000 --- a/bom.sc +++ /dev/null @@ -1,234 +0,0 @@ -import mill._, scalalib._ - -object IWMaterials { - - object Versions { - val akka = "2.6.16" - val akkaHttp = "10.2.4" - val cats = "2.7.0" - val elastic4s = "7.12.2" - val http4s = "0.23.10" - val http4sPac4J = "4.0.0" - val laminar = "0.14.2" - val laminext = laminar - val logbackClassic = "1.2.10" - val pac4j = "5.2.0" - val play = "2.8.8" - val playJson = "2.9.2" - val refined = "0.9.29" - val scalaTest = "3.2.9" - val slf4j = "1.7.36" - val slick = "3.3.3" - val sttpClient = "3.5.0" - val tapir = "0.20.1" - val urlDsl = "0.4.0" - val waypoint = "0.5.0" - val zio = "2.0.0-RC2" - val zioConfig = "3.0.0-RC2" - val zioInteropCats = "3.3.0-RC2" - val zioJson = "0.3.0-RC3" - val zioLogging = "2.0.0-RC5" - val zioPrelude = "1.0.0-RC10" - val zioZMX = "0.0.11" - } - - object Deps extends AkkaLibs with SlickLibs { - import IWMaterials.{Versions => V} - - val zioOrg = "dev.zio" - - def zioLib(name: String, version: String): Dep = - ivy"$zioOrg::zio-$name::$version" - - lazy val zio: Dep = ivy"$zioOrg::zio:${V.zio}" - - lazy val zioTest: Dep = zioLib("test", V.zio) - lazy val zioTestSbt: Dep = zioLib("test-sbt", V.zio) - - lazy val zioConfig: Dep = zioLib("config", V.zioConfig) - lazy val zioConfigTypesafe: Dep = - zioLib("config-typesafe", V.zioConfig) - lazy val zioConfigMagnolia: Dep = - zioLib("config-magnolia", V.zioConfig) - - lazy val zioJson: Dep = zioLib("json", V.zioJson) - lazy val zioLogging: Dep = zioLib("logging", V.zioLogging) - lazy val zioLoggingSlf4j: Dep = - zioLib("logging-slf4j", V.zioLogging) - lazy val zioPrelude: Dep = zioLib("prelude", V.zioPrelude) - lazy val zioStreams: Dep = zioLib("streams", V.zio) - lazy val zioZMX: Dep = zioLib("zmx", V.zioZMX) - lazy val zioInteropCats: Dep = - zioLib("interop-cats", V.zioInteropCats) - - lazy val catsCore: Dep = ivy"org.typelevel::cats-core::${V.cats}" - - lazy val refined: Dep = ivy"eu.timepit::refined::${V.refined}" - - /* What is the equivalent? ZIOModule with prepared test config? - def useZIO(testConf: Configuration*): Agg[Dep] = Agg( - zio, - zioTest, - zioTestSbt, - testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework") - ) - */ - - /* - def useZIOAll(testConf: Configuration*): Seq[Def.Setting[_]] = - useZIO(testConf: _*) ++ Seq( - zioStreams, - zioConfig, - zioConfigTypesafe, - zioConfigMagnolia, - zioJson, - zioZMX, - zioLogging, - zioPrelude - ) - */ - - private val tapirOrg = "com.softwaremill.sttp.tapir" - def tapirLib(name: String): Dep = - ivy"${tapirOrg}::tapir-$name::${V.tapir}" - - lazy val tapirCore: Dep = tapirLib("core") - lazy val tapirZIO: Dep = tapirLib("zio") - lazy val tapirZIOJson: Dep = tapirLib("json-zio") - lazy val tapirSttpClient: Dep = tapirLib("sttp-client") - lazy val tapirCats: Dep = tapirLib("cats") - lazy val tapirZIOHttp4sServer: Dep = tapirLib("zio-http4s-server") - - val sttpClientOrg = "com.softwaremill.sttp.client3" - def sttpClientLib(name: String): Dep = - 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}" - - lazy val http4sPac4J: Dep = - ivy"org.pac4j::http4s-pac4j:${V.http4sPac4J}" - lazy val pac4jOIDC: Dep = - ivy"org.pac4j:pac4j-oidc:${V.pac4j}" - - lazy val scalaTest: Dep = - ivy"org.scalatest::scalatest:${V.scalaTest}" - lazy val scalaTestPlusScalacheck: Dep = - ivy"org.scalatestplus::scalacheck-1-15:3.2.9.0" - lazy val playScalaTest: Dep = - ivy"org.scalatestplus.play::scalatestplus-play:5.1.0" - - private val playOrg = "com.typesafe.play" - lazy val playMailer: Dep = ivy"${playOrg}::play-mailer:8.0.1" - lazy val playServer: Dep = ivy"${playOrg}::play-server:${V.play}" - lazy val playAkkaServer: Dep = - ivy"${playOrg}::play-akka-http-server:${V.play}" - lazy val play: Dep = ivy"${playOrg}::play:${V.play}" - lazy val playAhcWs: Dep = ivy"${playOrg}::play-ahc-ws:${V.play}" - lazy val playJson: Dep = ivy"${playOrg}::play-json:${V.playJson}" - - private val elastic4sOrg = "com.sksamuel.elastic4s" - lazy val useElastic4S: Agg[Dep] = Agg( - ivy"${elastic4sOrg}::elastic4s-core:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-client-akka:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-http-streams:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-json-play:${V.elastic4s}" - ) - - lazy val laminar: Dep = ivy"com.raquo::laminar::${V.laminar}" - - private def laminext(name: String): Dep = - ivy"io.laminext::$name::${V.laminar}" - - lazy val laminextCore: Dep = laminext("core") - lazy val laminextTailwind: Dep = laminext("tailwind") - lazy val laminextFetch: Dep = laminext("fetch") - lazy val laminextValidationCore: Dep = laminext("validation-core") - lazy val laminextUI: Dep = laminext("ui") - - lazy val waypoint: Dep = - ivy"com.raquo::waypoint::${V.waypoint}" - - lazy val urlDsl: Dep = - ivy"be.doeraene::url-dsl::${V.urlDsl}" - - lazy val scalaJavaTime: Dep = - ivy"io.github.cquiroz::scala-java-time::2.3.0" - - lazy val scalaJavaLocales: Dep = - ivy"io.github.cquiroz::scala-java-locales::1.2.1" - - lazy val logbackClassic: Dep = - ivy"ch.qos.logback:logback-classic:${V.logbackClassic}" - } - - trait AkkaLibs { - - self: SlickLibs => - - object akka { - val V = Versions.akka - val tOrg = "com.typesafe.akka" - val lOrg = "com.lightbend.akka" - - def akkaMod(name: String): Dep = - ivy"$tOrg::akka-$name:$V" - - lazy val actor: Dep = akkaMod("actor") - lazy val actorTyped: Dep = akkaMod("actor-typed") - lazy val stream: Dep = akkaMod("stream") - lazy val persistence: Dep = akkaMod("persistence-typed") - lazy val persistenceQuery: Dep = akkaMod("persistence-query") - lazy val persistenceJdbc: Dep = - ivy"$lOrg::akka-persistence-jdbc:5.0.4" - val persistenceTestKit: Dep = ivy"$tOrg::akka-persistence-testkit:$V" - - object http { - val V = Versions.akkaHttp - - lazy val http: Dep = ivy"$tOrg::akka-http:$V" - lazy val sprayJson: Dep = ivy"$tOrg::akka-http-spray-json:$V" - - } - - object projection { - val V = "1.2.2" - - lazy val core: Dep = - ivy"$lOrg::akka-projection-core:$V" - lazy val eventsourced: Dep = - ivy"$lOrg::akka-projection-eventsourced:$V" - lazy val slick: Dep = - ivy"$lOrg::akka-projection-slick:$V" - lazy val jdbc: Dep = - ivy"$lOrg::akka-projection-jdbc:$V" - } - - object profiles { - // TODO: deal with cross-version for Scala3 (for3Use2_13) - lazy val eventsourcedJdbcProjection: Agg[Dep] = Agg( - persistenceQuery, - projection.core, - projection.eventsourced, - projection.slick, - persistenceJdbc - ) ++ slick.default - } - } - } - - trait SlickLibs { - object slick { - val V = IWMaterials.Versions.slick - val org = "com.typesafe.slick" - - lazy val slick: Dep = ivy"$org::slick:$V" - lazy val hikaricp: Dep = ivy"$org::slick-hikaricp:$V" - lazy val default: Agg[Dep] = Agg(slick, hikaricp) - } - } - -} diff --git a/build.sbt b/build.sbt new file mode 100644 index 0000000..a8bc367 --- /dev/null +++ b/build.sbt @@ -0,0 +1,123 @@ +ThisBuild / scalaVersion := scala3Version + +publishToIW + +lazy val core = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .settings(name := "iw-support-core") + .in(file("core")) + .settings(IWDeps.zioPrelude) + +lazy val `tapir-support` = crossProject(JSPlatform, JVMPlatform) + .in(file("tapir")) + .settings(name := "iw-support-tapir") + .settings( + IWDeps.tapirCore, + IWDeps.tapirZIOJson, + IWDeps.useZIOJson, + IWDeps.tapirSttpClient + ) + .jvmSettings( + IWDeps.tapirZIO, + IWDeps.tapirZIOHttp4sServer, + IWDeps.useZIOJson, + IWDeps.sttpClientLib("async-http-client-backend-zio"), + IWDeps.zioLib("interop-reactivestreams", "2.0.0"), + IWDeps.zioLib("nio", "2.0.0"), + excludeDependencies += // Gets transitively dragged in by zio-nio, conflicting with _3 + ExclusionRule("org.scala-lang.modules", "scala-collection-compat_2.13") + ) + +lazy val codecs = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .in(file("codecs")) + .settings(name := "iw-support-codecs") + .settings( + IWDeps.useZIOJson, + excludeDependencies += // Gets transitively dragged in by zio-nio, conflicting with _3 + ExclusionRule("org.scala-lang.modules", "scala-collection-compat_2.13") + ) + .dependsOn(core, `tapir-support`) + +lazy val `mongo-support` = project + .in(file("mongo")) + .configs(IntegrationTest) + .settings(name := "iw-support-mongo") + .settings( + Defaults.itSettings, + IWDeps.useZIO(Test, IntegrationTest), + IWDeps.useZIOJson, + IWDeps.zioConfig, + libraryDependencies += ("org.mongodb.scala" %% "mongo-scala-driver" % "4.2.3") + .cross(CrossVersion.for3Use2_13) + ) + +lazy val `akka-persistence-support` = project + .in(file("akka-persistence")) + .settings(name := "iw-support-akka-persistence") + .settings( + IWDeps.useZIO(Test), + IWDeps.useZIOJson, + IWDeps.zioConfig, + libraryDependencies += IWDeps.akka.modules.persistence + .cross(CrossVersion.for3Use2_13), + libraryDependencies += "com.typesafe.akka" %% "akka-cluster-sharding-typed" % IWDeps.akka.V cross (CrossVersion.for3Use2_13), + IWDeps.akka.profiles.eventsourcedJdbcProjection + ) + +lazy val ui = (project in file("ui")) + .enablePlugins(ScalaJSPlugin) + .settings(name := "iw-support-ui") + .settings( + IWDeps.useZIO(Test), + IWDeps.laminar, + IWDeps.useZIOJson, + IWDeps.waypoint, + IWDeps.urlDsl, + IWDeps.laminextCore, + IWDeps.laminextUI, + IWDeps.laminextTailwind, + IWDeps.laminextValidationCore + ) + +lazy val `ui-model` = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .in(file("ui/model")) + .settings(name := "iw-support-ui-model") + .dependsOn(core) + +lazy val `ui-components` = (project in file("ui/components")) + .enablePlugins(ScalaJSPlugin) + .settings(name := "iw-support-ui-components") + .settings( + IWDeps.useZIO(Test), + IWDeps.zioPrelude, + IWDeps.laminar, + IWDeps.useZIOJson, + IWDeps.waypoint, + IWDeps.urlDsl, + IWDeps.laminextCore, + IWDeps.laminextUI, + IWDeps.laminextTailwind, + IWDeps.laminextValidationCore + ) + .dependsOn(`ui-model`.js) + +lazy val root = (project in file(".")) + .settings(name := "iw-support", publish / skip := true) + // Auto activates for all projects, but make sure we have required dependencies + .enablePlugins(IWScalaProjectPlugin, GitVersioning) + .aggregate( + core.js, + core.jvm, + codecs.js, + codecs.jvm, + `tapir-support`.js, + `tapir-support`.jvm, + `mongo-support`, + `akka-persistence-support`, + ui, + `ui-model`.js, + `ui-model`.jvm, + `ui-components` + ) diff --git a/.sbtopts b/.sbtopts new file mode 100644 index 0000000..6913385 --- /dev/null +++ b/.sbtopts @@ -0,0 +1 @@ +-mem 2048 -J-XX:+UseG1GC diff --git a/bom.sc b/bom.sc deleted file mode 100644 index 636a511..0000000 --- a/bom.sc +++ /dev/null @@ -1,234 +0,0 @@ -import mill._, scalalib._ - -object IWMaterials { - - object Versions { - val akka = "2.6.16" - val akkaHttp = "10.2.4" - val cats = "2.7.0" - val elastic4s = "7.12.2" - val http4s = "0.23.10" - val http4sPac4J = "4.0.0" - val laminar = "0.14.2" - val laminext = laminar - val logbackClassic = "1.2.10" - val pac4j = "5.2.0" - val play = "2.8.8" - val playJson = "2.9.2" - val refined = "0.9.29" - val scalaTest = "3.2.9" - val slf4j = "1.7.36" - val slick = "3.3.3" - val sttpClient = "3.5.0" - val tapir = "0.20.1" - val urlDsl = "0.4.0" - val waypoint = "0.5.0" - val zio = "2.0.0-RC2" - val zioConfig = "3.0.0-RC2" - val zioInteropCats = "3.3.0-RC2" - val zioJson = "0.3.0-RC3" - val zioLogging = "2.0.0-RC5" - val zioPrelude = "1.0.0-RC10" - val zioZMX = "0.0.11" - } - - object Deps extends AkkaLibs with SlickLibs { - import IWMaterials.{Versions => V} - - val zioOrg = "dev.zio" - - def zioLib(name: String, version: String): Dep = - ivy"$zioOrg::zio-$name::$version" - - lazy val zio: Dep = ivy"$zioOrg::zio:${V.zio}" - - lazy val zioTest: Dep = zioLib("test", V.zio) - lazy val zioTestSbt: Dep = zioLib("test-sbt", V.zio) - - lazy val zioConfig: Dep = zioLib("config", V.zioConfig) - lazy val zioConfigTypesafe: Dep = - zioLib("config-typesafe", V.zioConfig) - lazy val zioConfigMagnolia: Dep = - zioLib("config-magnolia", V.zioConfig) - - lazy val zioJson: Dep = zioLib("json", V.zioJson) - lazy val zioLogging: Dep = zioLib("logging", V.zioLogging) - lazy val zioLoggingSlf4j: Dep = - zioLib("logging-slf4j", V.zioLogging) - lazy val zioPrelude: Dep = zioLib("prelude", V.zioPrelude) - lazy val zioStreams: Dep = zioLib("streams", V.zio) - lazy val zioZMX: Dep = zioLib("zmx", V.zioZMX) - lazy val zioInteropCats: Dep = - zioLib("interop-cats", V.zioInteropCats) - - lazy val catsCore: Dep = ivy"org.typelevel::cats-core::${V.cats}" - - lazy val refined: Dep = ivy"eu.timepit::refined::${V.refined}" - - /* What is the equivalent? ZIOModule with prepared test config? - def useZIO(testConf: Configuration*): Agg[Dep] = Agg( - zio, - zioTest, - zioTestSbt, - testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework") - ) - */ - - /* - def useZIOAll(testConf: Configuration*): Seq[Def.Setting[_]] = - useZIO(testConf: _*) ++ Seq( - zioStreams, - zioConfig, - zioConfigTypesafe, - zioConfigMagnolia, - zioJson, - zioZMX, - zioLogging, - zioPrelude - ) - */ - - private val tapirOrg = "com.softwaremill.sttp.tapir" - def tapirLib(name: String): Dep = - ivy"${tapirOrg}::tapir-$name::${V.tapir}" - - lazy val tapirCore: Dep = tapirLib("core") - lazy val tapirZIO: Dep = tapirLib("zio") - lazy val tapirZIOJson: Dep = tapirLib("json-zio") - lazy val tapirSttpClient: Dep = tapirLib("sttp-client") - lazy val tapirCats: Dep = tapirLib("cats") - lazy val tapirZIOHttp4sServer: Dep = tapirLib("zio-http4s-server") - - val sttpClientOrg = "com.softwaremill.sttp.client3" - def sttpClientLib(name: String): Dep = - 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}" - - lazy val http4sPac4J: Dep = - ivy"org.pac4j::http4s-pac4j:${V.http4sPac4J}" - lazy val pac4jOIDC: Dep = - ivy"org.pac4j:pac4j-oidc:${V.pac4j}" - - lazy val scalaTest: Dep = - ivy"org.scalatest::scalatest:${V.scalaTest}" - lazy val scalaTestPlusScalacheck: Dep = - ivy"org.scalatestplus::scalacheck-1-15:3.2.9.0" - lazy val playScalaTest: Dep = - ivy"org.scalatestplus.play::scalatestplus-play:5.1.0" - - private val playOrg = "com.typesafe.play" - lazy val playMailer: Dep = ivy"${playOrg}::play-mailer:8.0.1" - lazy val playServer: Dep = ivy"${playOrg}::play-server:${V.play}" - lazy val playAkkaServer: Dep = - ivy"${playOrg}::play-akka-http-server:${V.play}" - lazy val play: Dep = ivy"${playOrg}::play:${V.play}" - lazy val playAhcWs: Dep = ivy"${playOrg}::play-ahc-ws:${V.play}" - lazy val playJson: Dep = ivy"${playOrg}::play-json:${V.playJson}" - - private val elastic4sOrg = "com.sksamuel.elastic4s" - lazy val useElastic4S: Agg[Dep] = Agg( - ivy"${elastic4sOrg}::elastic4s-core:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-client-akka:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-http-streams:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-json-play:${V.elastic4s}" - ) - - lazy val laminar: Dep = ivy"com.raquo::laminar::${V.laminar}" - - private def laminext(name: String): Dep = - ivy"io.laminext::$name::${V.laminar}" - - lazy val laminextCore: Dep = laminext("core") - lazy val laminextTailwind: Dep = laminext("tailwind") - lazy val laminextFetch: Dep = laminext("fetch") - lazy val laminextValidationCore: Dep = laminext("validation-core") - lazy val laminextUI: Dep = laminext("ui") - - lazy val waypoint: Dep = - ivy"com.raquo::waypoint::${V.waypoint}" - - lazy val urlDsl: Dep = - ivy"be.doeraene::url-dsl::${V.urlDsl}" - - lazy val scalaJavaTime: Dep = - ivy"io.github.cquiroz::scala-java-time::2.3.0" - - lazy val scalaJavaLocales: Dep = - ivy"io.github.cquiroz::scala-java-locales::1.2.1" - - lazy val logbackClassic: Dep = - ivy"ch.qos.logback:logback-classic:${V.logbackClassic}" - } - - trait AkkaLibs { - - self: SlickLibs => - - object akka { - val V = Versions.akka - val tOrg = "com.typesafe.akka" - val lOrg = "com.lightbend.akka" - - def akkaMod(name: String): Dep = - ivy"$tOrg::akka-$name:$V" - - lazy val actor: Dep = akkaMod("actor") - lazy val actorTyped: Dep = akkaMod("actor-typed") - lazy val stream: Dep = akkaMod("stream") - lazy val persistence: Dep = akkaMod("persistence-typed") - lazy val persistenceQuery: Dep = akkaMod("persistence-query") - lazy val persistenceJdbc: Dep = - ivy"$lOrg::akka-persistence-jdbc:5.0.4" - val persistenceTestKit: Dep = ivy"$tOrg::akka-persistence-testkit:$V" - - object http { - val V = Versions.akkaHttp - - lazy val http: Dep = ivy"$tOrg::akka-http:$V" - lazy val sprayJson: Dep = ivy"$tOrg::akka-http-spray-json:$V" - - } - - object projection { - val V = "1.2.2" - - lazy val core: Dep = - ivy"$lOrg::akka-projection-core:$V" - lazy val eventsourced: Dep = - ivy"$lOrg::akka-projection-eventsourced:$V" - lazy val slick: Dep = - ivy"$lOrg::akka-projection-slick:$V" - lazy val jdbc: Dep = - ivy"$lOrg::akka-projection-jdbc:$V" - } - - object profiles { - // TODO: deal with cross-version for Scala3 (for3Use2_13) - lazy val eventsourcedJdbcProjection: Agg[Dep] = Agg( - persistenceQuery, - projection.core, - projection.eventsourced, - projection.slick, - persistenceJdbc - ) ++ slick.default - } - } - } - - trait SlickLibs { - object slick { - val V = IWMaterials.Versions.slick - val org = "com.typesafe.slick" - - lazy val slick: Dep = ivy"$org::slick:$V" - lazy val hikaricp: Dep = ivy"$org::slick-hikaricp:$V" - lazy val default: Agg[Dep] = Agg(slick, hikaricp) - } - } - -} diff --git a/build.sbt b/build.sbt new file mode 100644 index 0000000..a8bc367 --- /dev/null +++ b/build.sbt @@ -0,0 +1,123 @@ +ThisBuild / scalaVersion := scala3Version + +publishToIW + +lazy val core = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .settings(name := "iw-support-core") + .in(file("core")) + .settings(IWDeps.zioPrelude) + +lazy val `tapir-support` = crossProject(JSPlatform, JVMPlatform) + .in(file("tapir")) + .settings(name := "iw-support-tapir") + .settings( + IWDeps.tapirCore, + IWDeps.tapirZIOJson, + IWDeps.useZIOJson, + IWDeps.tapirSttpClient + ) + .jvmSettings( + IWDeps.tapirZIO, + IWDeps.tapirZIOHttp4sServer, + IWDeps.useZIOJson, + IWDeps.sttpClientLib("async-http-client-backend-zio"), + IWDeps.zioLib("interop-reactivestreams", "2.0.0"), + IWDeps.zioLib("nio", "2.0.0"), + excludeDependencies += // Gets transitively dragged in by zio-nio, conflicting with _3 + ExclusionRule("org.scala-lang.modules", "scala-collection-compat_2.13") + ) + +lazy val codecs = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .in(file("codecs")) + .settings(name := "iw-support-codecs") + .settings( + IWDeps.useZIOJson, + excludeDependencies += // Gets transitively dragged in by zio-nio, conflicting with _3 + ExclusionRule("org.scala-lang.modules", "scala-collection-compat_2.13") + ) + .dependsOn(core, `tapir-support`) + +lazy val `mongo-support` = project + .in(file("mongo")) + .configs(IntegrationTest) + .settings(name := "iw-support-mongo") + .settings( + Defaults.itSettings, + IWDeps.useZIO(Test, IntegrationTest), + IWDeps.useZIOJson, + IWDeps.zioConfig, + libraryDependencies += ("org.mongodb.scala" %% "mongo-scala-driver" % "4.2.3") + .cross(CrossVersion.for3Use2_13) + ) + +lazy val `akka-persistence-support` = project + .in(file("akka-persistence")) + .settings(name := "iw-support-akka-persistence") + .settings( + IWDeps.useZIO(Test), + IWDeps.useZIOJson, + IWDeps.zioConfig, + libraryDependencies += IWDeps.akka.modules.persistence + .cross(CrossVersion.for3Use2_13), + libraryDependencies += "com.typesafe.akka" %% "akka-cluster-sharding-typed" % IWDeps.akka.V cross (CrossVersion.for3Use2_13), + IWDeps.akka.profiles.eventsourcedJdbcProjection + ) + +lazy val ui = (project in file("ui")) + .enablePlugins(ScalaJSPlugin) + .settings(name := "iw-support-ui") + .settings( + IWDeps.useZIO(Test), + IWDeps.laminar, + IWDeps.useZIOJson, + IWDeps.waypoint, + IWDeps.urlDsl, + IWDeps.laminextCore, + IWDeps.laminextUI, + IWDeps.laminextTailwind, + IWDeps.laminextValidationCore + ) + +lazy val `ui-model` = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .in(file("ui/model")) + .settings(name := "iw-support-ui-model") + .dependsOn(core) + +lazy val `ui-components` = (project in file("ui/components")) + .enablePlugins(ScalaJSPlugin) + .settings(name := "iw-support-ui-components") + .settings( + IWDeps.useZIO(Test), + IWDeps.zioPrelude, + IWDeps.laminar, + IWDeps.useZIOJson, + IWDeps.waypoint, + IWDeps.urlDsl, + IWDeps.laminextCore, + IWDeps.laminextUI, + IWDeps.laminextTailwind, + IWDeps.laminextValidationCore + ) + .dependsOn(`ui-model`.js) + +lazy val root = (project in file(".")) + .settings(name := "iw-support", publish / skip := true) + // Auto activates for all projects, but make sure we have required dependencies + .enablePlugins(IWScalaProjectPlugin, GitVersioning) + .aggregate( + core.js, + core.jvm, + codecs.js, + codecs.jvm, + `tapir-support`.js, + `tapir-support`.jvm, + `mongo-support`, + `akka-persistence-support`, + ui, + `ui-model`.js, + `ui-model`.jvm, + `ui-components` + ) diff --git a/build.sc b/build.sc deleted file mode 100644 index 3f3da4f..0000000 --- a/build.sc +++ /dev/null @@ -1,146 +0,0 @@ -import mill._, scalalib._, scalajslib._ - -import $file.bom - -object support { - val Deps = bom.IWMaterials.Deps - val Versions = bom.IWMaterials.Versions - - trait CommonModule extends ScalaModule { - def scalaVersion = "3.1.1" - def scalacOptions = T { - super.scalacOptions() ++ Seq( - "-encoding", - "utf8", - "-deprecation", - "-explain-types", - "-explain", - "-feature", - "-language:experimental.macros", - "-language:higherKinds", - "-language:implicitConversions", - "-unchecked", - "-Xfatal-warnings", - "-Ykind-projector" - ) - } - } - - trait CommonJSModule extends CommonModule with ScalaJSModule { - def scalaJSVersion = "1.9.0" - } - - trait CrossPlatformModule extends Module { outer => - def ivyDeps: T[Agg[Dep]] = Agg[Dep]() - def jsDeps: T[Agg[Dep]] = Agg[Dep]() - def jvmDeps: T[Agg[Dep]] = Agg[Dep]() - def moduleDeps: Seq[Module] = Seq[Module]() - - trait PlatformModule extends CommonModule { - def platform: String - override def millSourcePath = outer.millSourcePath - override def ivyDeps = outer.ivyDeps() ++ (platform match { - case "js" => jsDeps() - case _ => jvmDeps() - }) - override def moduleDeps = outer.moduleDeps.collect { - case m: CrossPlatformModule => - platform match { - case "js" => m.js - case _ => m.jvm - } - case m: JavaModule => m - } - } - - trait JsModule extends PlatformModule with CommonJSModule { - def platform = "js" - } - - trait JvmModule extends PlatformModule { - def platform = "jvm" - } - - val js: JsModule - val jvm: JvmModule - } - - trait PureCrossModule extends CrossPlatformModule { - override object js extends JsModule - override object jvm extends JvmModule - } - - trait PureCrossSbtModule extends CrossPlatformModule { - override object js extends JsModule with SbtModule - override object jvm extends JvmModule with SbtModule - } - - trait FullCrossSbtModule extends CrossPlatformModule { - trait FullSources extends JavaModule { self: PlatformModule => - override def sources = T.sources( - millSourcePath / platform / "src" / "main" / "scala", - millSourcePath / "shared" / "src" / "main" / "scala" - ) - - override def resources = T.sources( - millSourcePath / platform / "src" / "main" / "resources", - millSourcePath / "shared" / "src" / "main" / "resources" - ) - } - - override object js extends JsModule with FullSources - override object jvm extends JvmModule with FullSources - } - -} - -import support._ - -object mongo extends CommonModule { - def ivyDeps = Agg( - Deps.zio, - Deps.zioJson, - Deps.zioConfig, - ivy"org.mongodb.scala::mongo-scala-driver:4.2.3".withDottyCompat( - scalaVersion() - ) - ) -} - -object tapir extends FullCrossSbtModule { - def ivyDeps = Agg(Deps.tapirCore, Deps.tapirZIOJson, Deps.zioJson) - def jvmDeps = Agg(Deps.tapirZIO, Deps.tapirZIOHttp4sServer) - def jsDeps = Agg(Deps.tapirSttpClient) -} - -object akkaPersistence extends CommonModule { - def millSourcePath = build.millSourcePath / "akka-persistence" - def ivyDeps = (Agg( - Deps.akka.persistenceQuery, - Deps.akka.persistenceJdbc, - Deps.akka.projection.core, - Deps.akka.projection.eventsourced, - Deps.akka.projection.slick - ) ++ Deps.slick.default).map(_.withDottyCompat(scalaVersion())) ++ Agg( - Deps.zio, - Deps.zioJson, - Deps.zioConfig, - Deps.akka.persistence.withDottyCompat(scalaVersion()), - ivy"com.typesafe.akka::akka-cluster-sharding-typed:${Deps.akka.V}" - .withDottyCompat(scalaVersion()) - ) -} - -object ui extends CommonJSModule { - def ivyDeps = Agg( - Deps.zio, - Deps.laminar, - Deps.zioJson, - Deps.waypoint, - Deps.urlDsl, - Deps.laminextCore, - Deps.laminextUI, - Deps.laminextTailwind, - Deps.laminextValidationCore - ) -} diff --git a/.sbtopts b/.sbtopts new file mode 100644 index 0000000..6913385 --- /dev/null +++ b/.sbtopts @@ -0,0 +1 @@ +-mem 2048 -J-XX:+UseG1GC diff --git a/bom.sc b/bom.sc deleted file mode 100644 index 636a511..0000000 --- a/bom.sc +++ /dev/null @@ -1,234 +0,0 @@ -import mill._, scalalib._ - -object IWMaterials { - - object Versions { - val akka = "2.6.16" - val akkaHttp = "10.2.4" - val cats = "2.7.0" - val elastic4s = "7.12.2" - val http4s = "0.23.10" - val http4sPac4J = "4.0.0" - val laminar = "0.14.2" - val laminext = laminar - val logbackClassic = "1.2.10" - val pac4j = "5.2.0" - val play = "2.8.8" - val playJson = "2.9.2" - val refined = "0.9.29" - val scalaTest = "3.2.9" - val slf4j = "1.7.36" - val slick = "3.3.3" - val sttpClient = "3.5.0" - val tapir = "0.20.1" - val urlDsl = "0.4.0" - val waypoint = "0.5.0" - val zio = "2.0.0-RC2" - val zioConfig = "3.0.0-RC2" - val zioInteropCats = "3.3.0-RC2" - val zioJson = "0.3.0-RC3" - val zioLogging = "2.0.0-RC5" - val zioPrelude = "1.0.0-RC10" - val zioZMX = "0.0.11" - } - - object Deps extends AkkaLibs with SlickLibs { - import IWMaterials.{Versions => V} - - val zioOrg = "dev.zio" - - def zioLib(name: String, version: String): Dep = - ivy"$zioOrg::zio-$name::$version" - - lazy val zio: Dep = ivy"$zioOrg::zio:${V.zio}" - - lazy val zioTest: Dep = zioLib("test", V.zio) - lazy val zioTestSbt: Dep = zioLib("test-sbt", V.zio) - - lazy val zioConfig: Dep = zioLib("config", V.zioConfig) - lazy val zioConfigTypesafe: Dep = - zioLib("config-typesafe", V.zioConfig) - lazy val zioConfigMagnolia: Dep = - zioLib("config-magnolia", V.zioConfig) - - lazy val zioJson: Dep = zioLib("json", V.zioJson) - lazy val zioLogging: Dep = zioLib("logging", V.zioLogging) - lazy val zioLoggingSlf4j: Dep = - zioLib("logging-slf4j", V.zioLogging) - lazy val zioPrelude: Dep = zioLib("prelude", V.zioPrelude) - lazy val zioStreams: Dep = zioLib("streams", V.zio) - lazy val zioZMX: Dep = zioLib("zmx", V.zioZMX) - lazy val zioInteropCats: Dep = - zioLib("interop-cats", V.zioInteropCats) - - lazy val catsCore: Dep = ivy"org.typelevel::cats-core::${V.cats}" - - lazy val refined: Dep = ivy"eu.timepit::refined::${V.refined}" - - /* What is the equivalent? ZIOModule with prepared test config? - def useZIO(testConf: Configuration*): Agg[Dep] = Agg( - zio, - zioTest, - zioTestSbt, - testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework") - ) - */ - - /* - def useZIOAll(testConf: Configuration*): Seq[Def.Setting[_]] = - useZIO(testConf: _*) ++ Seq( - zioStreams, - zioConfig, - zioConfigTypesafe, - zioConfigMagnolia, - zioJson, - zioZMX, - zioLogging, - zioPrelude - ) - */ - - private val tapirOrg = "com.softwaremill.sttp.tapir" - def tapirLib(name: String): Dep = - ivy"${tapirOrg}::tapir-$name::${V.tapir}" - - lazy val tapirCore: Dep = tapirLib("core") - lazy val tapirZIO: Dep = tapirLib("zio") - lazy val tapirZIOJson: Dep = tapirLib("json-zio") - lazy val tapirSttpClient: Dep = tapirLib("sttp-client") - lazy val tapirCats: Dep = tapirLib("cats") - lazy val tapirZIOHttp4sServer: Dep = tapirLib("zio-http4s-server") - - val sttpClientOrg = "com.softwaremill.sttp.client3" - def sttpClientLib(name: String): Dep = - 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}" - - lazy val http4sPac4J: Dep = - ivy"org.pac4j::http4s-pac4j:${V.http4sPac4J}" - lazy val pac4jOIDC: Dep = - ivy"org.pac4j:pac4j-oidc:${V.pac4j}" - - lazy val scalaTest: Dep = - ivy"org.scalatest::scalatest:${V.scalaTest}" - lazy val scalaTestPlusScalacheck: Dep = - ivy"org.scalatestplus::scalacheck-1-15:3.2.9.0" - lazy val playScalaTest: Dep = - ivy"org.scalatestplus.play::scalatestplus-play:5.1.0" - - private val playOrg = "com.typesafe.play" - lazy val playMailer: Dep = ivy"${playOrg}::play-mailer:8.0.1" - lazy val playServer: Dep = ivy"${playOrg}::play-server:${V.play}" - lazy val playAkkaServer: Dep = - ivy"${playOrg}::play-akka-http-server:${V.play}" - lazy val play: Dep = ivy"${playOrg}::play:${V.play}" - lazy val playAhcWs: Dep = ivy"${playOrg}::play-ahc-ws:${V.play}" - lazy val playJson: Dep = ivy"${playOrg}::play-json:${V.playJson}" - - private val elastic4sOrg = "com.sksamuel.elastic4s" - lazy val useElastic4S: Agg[Dep] = Agg( - ivy"${elastic4sOrg}::elastic4s-core:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-client-akka:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-http-streams:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-json-play:${V.elastic4s}" - ) - - lazy val laminar: Dep = ivy"com.raquo::laminar::${V.laminar}" - - private def laminext(name: String): Dep = - ivy"io.laminext::$name::${V.laminar}" - - lazy val laminextCore: Dep = laminext("core") - lazy val laminextTailwind: Dep = laminext("tailwind") - lazy val laminextFetch: Dep = laminext("fetch") - lazy val laminextValidationCore: Dep = laminext("validation-core") - lazy val laminextUI: Dep = laminext("ui") - - lazy val waypoint: Dep = - ivy"com.raquo::waypoint::${V.waypoint}" - - lazy val urlDsl: Dep = - ivy"be.doeraene::url-dsl::${V.urlDsl}" - - lazy val scalaJavaTime: Dep = - ivy"io.github.cquiroz::scala-java-time::2.3.0" - - lazy val scalaJavaLocales: Dep = - ivy"io.github.cquiroz::scala-java-locales::1.2.1" - - lazy val logbackClassic: Dep = - ivy"ch.qos.logback:logback-classic:${V.logbackClassic}" - } - - trait AkkaLibs { - - self: SlickLibs => - - object akka { - val V = Versions.akka - val tOrg = "com.typesafe.akka" - val lOrg = "com.lightbend.akka" - - def akkaMod(name: String): Dep = - ivy"$tOrg::akka-$name:$V" - - lazy val actor: Dep = akkaMod("actor") - lazy val actorTyped: Dep = akkaMod("actor-typed") - lazy val stream: Dep = akkaMod("stream") - lazy val persistence: Dep = akkaMod("persistence-typed") - lazy val persistenceQuery: Dep = akkaMod("persistence-query") - lazy val persistenceJdbc: Dep = - ivy"$lOrg::akka-persistence-jdbc:5.0.4" - val persistenceTestKit: Dep = ivy"$tOrg::akka-persistence-testkit:$V" - - object http { - val V = Versions.akkaHttp - - lazy val http: Dep = ivy"$tOrg::akka-http:$V" - lazy val sprayJson: Dep = ivy"$tOrg::akka-http-spray-json:$V" - - } - - object projection { - val V = "1.2.2" - - lazy val core: Dep = - ivy"$lOrg::akka-projection-core:$V" - lazy val eventsourced: Dep = - ivy"$lOrg::akka-projection-eventsourced:$V" - lazy val slick: Dep = - ivy"$lOrg::akka-projection-slick:$V" - lazy val jdbc: Dep = - ivy"$lOrg::akka-projection-jdbc:$V" - } - - object profiles { - // TODO: deal with cross-version for Scala3 (for3Use2_13) - lazy val eventsourcedJdbcProjection: Agg[Dep] = Agg( - persistenceQuery, - projection.core, - projection.eventsourced, - projection.slick, - persistenceJdbc - ) ++ slick.default - } - } - } - - trait SlickLibs { - object slick { - val V = IWMaterials.Versions.slick - val org = "com.typesafe.slick" - - lazy val slick: Dep = ivy"$org::slick:$V" - lazy val hikaricp: Dep = ivy"$org::slick-hikaricp:$V" - lazy val default: Agg[Dep] = Agg(slick, hikaricp) - } - } - -} diff --git a/build.sbt b/build.sbt new file mode 100644 index 0000000..a8bc367 --- /dev/null +++ b/build.sbt @@ -0,0 +1,123 @@ +ThisBuild / scalaVersion := scala3Version + +publishToIW + +lazy val core = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .settings(name := "iw-support-core") + .in(file("core")) + .settings(IWDeps.zioPrelude) + +lazy val `tapir-support` = crossProject(JSPlatform, JVMPlatform) + .in(file("tapir")) + .settings(name := "iw-support-tapir") + .settings( + IWDeps.tapirCore, + IWDeps.tapirZIOJson, + IWDeps.useZIOJson, + IWDeps.tapirSttpClient + ) + .jvmSettings( + IWDeps.tapirZIO, + IWDeps.tapirZIOHttp4sServer, + IWDeps.useZIOJson, + IWDeps.sttpClientLib("async-http-client-backend-zio"), + IWDeps.zioLib("interop-reactivestreams", "2.0.0"), + IWDeps.zioLib("nio", "2.0.0"), + excludeDependencies += // Gets transitively dragged in by zio-nio, conflicting with _3 + ExclusionRule("org.scala-lang.modules", "scala-collection-compat_2.13") + ) + +lazy val codecs = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .in(file("codecs")) + .settings(name := "iw-support-codecs") + .settings( + IWDeps.useZIOJson, + excludeDependencies += // Gets transitively dragged in by zio-nio, conflicting with _3 + ExclusionRule("org.scala-lang.modules", "scala-collection-compat_2.13") + ) + .dependsOn(core, `tapir-support`) + +lazy val `mongo-support` = project + .in(file("mongo")) + .configs(IntegrationTest) + .settings(name := "iw-support-mongo") + .settings( + Defaults.itSettings, + IWDeps.useZIO(Test, IntegrationTest), + IWDeps.useZIOJson, + IWDeps.zioConfig, + libraryDependencies += ("org.mongodb.scala" %% "mongo-scala-driver" % "4.2.3") + .cross(CrossVersion.for3Use2_13) + ) + +lazy val `akka-persistence-support` = project + .in(file("akka-persistence")) + .settings(name := "iw-support-akka-persistence") + .settings( + IWDeps.useZIO(Test), + IWDeps.useZIOJson, + IWDeps.zioConfig, + libraryDependencies += IWDeps.akka.modules.persistence + .cross(CrossVersion.for3Use2_13), + libraryDependencies += "com.typesafe.akka" %% "akka-cluster-sharding-typed" % IWDeps.akka.V cross (CrossVersion.for3Use2_13), + IWDeps.akka.profiles.eventsourcedJdbcProjection + ) + +lazy val ui = (project in file("ui")) + .enablePlugins(ScalaJSPlugin) + .settings(name := "iw-support-ui") + .settings( + IWDeps.useZIO(Test), + IWDeps.laminar, + IWDeps.useZIOJson, + IWDeps.waypoint, + IWDeps.urlDsl, + IWDeps.laminextCore, + IWDeps.laminextUI, + IWDeps.laminextTailwind, + IWDeps.laminextValidationCore + ) + +lazy val `ui-model` = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .in(file("ui/model")) + .settings(name := "iw-support-ui-model") + .dependsOn(core) + +lazy val `ui-components` = (project in file("ui/components")) + .enablePlugins(ScalaJSPlugin) + .settings(name := "iw-support-ui-components") + .settings( + IWDeps.useZIO(Test), + IWDeps.zioPrelude, + IWDeps.laminar, + IWDeps.useZIOJson, + IWDeps.waypoint, + IWDeps.urlDsl, + IWDeps.laminextCore, + IWDeps.laminextUI, + IWDeps.laminextTailwind, + IWDeps.laminextValidationCore + ) + .dependsOn(`ui-model`.js) + +lazy val root = (project in file(".")) + .settings(name := "iw-support", publish / skip := true) + // Auto activates for all projects, but make sure we have required dependencies + .enablePlugins(IWScalaProjectPlugin, GitVersioning) + .aggregate( + core.js, + core.jvm, + codecs.js, + codecs.jvm, + `tapir-support`.js, + `tapir-support`.jvm, + `mongo-support`, + `akka-persistence-support`, + ui, + `ui-model`.js, + `ui-model`.jvm, + `ui-components` + ) diff --git a/build.sc b/build.sc deleted file mode 100644 index 3f3da4f..0000000 --- a/build.sc +++ /dev/null @@ -1,146 +0,0 @@ -import mill._, scalalib._, scalajslib._ - -import $file.bom - -object support { - val Deps = bom.IWMaterials.Deps - val Versions = bom.IWMaterials.Versions - - trait CommonModule extends ScalaModule { - def scalaVersion = "3.1.1" - def scalacOptions = T { - super.scalacOptions() ++ Seq( - "-encoding", - "utf8", - "-deprecation", - "-explain-types", - "-explain", - "-feature", - "-language:experimental.macros", - "-language:higherKinds", - "-language:implicitConversions", - "-unchecked", - "-Xfatal-warnings", - "-Ykind-projector" - ) - } - } - - trait CommonJSModule extends CommonModule with ScalaJSModule { - def scalaJSVersion = "1.9.0" - } - - trait CrossPlatformModule extends Module { outer => - def ivyDeps: T[Agg[Dep]] = Agg[Dep]() - def jsDeps: T[Agg[Dep]] = Agg[Dep]() - def jvmDeps: T[Agg[Dep]] = Agg[Dep]() - def moduleDeps: Seq[Module] = Seq[Module]() - - trait PlatformModule extends CommonModule { - def platform: String - override def millSourcePath = outer.millSourcePath - override def ivyDeps = outer.ivyDeps() ++ (platform match { - case "js" => jsDeps() - case _ => jvmDeps() - }) - override def moduleDeps = outer.moduleDeps.collect { - case m: CrossPlatformModule => - platform match { - case "js" => m.js - case _ => m.jvm - } - case m: JavaModule => m - } - } - - trait JsModule extends PlatformModule with CommonJSModule { - def platform = "js" - } - - trait JvmModule extends PlatformModule { - def platform = "jvm" - } - - val js: JsModule - val jvm: JvmModule - } - - trait PureCrossModule extends CrossPlatformModule { - override object js extends JsModule - override object jvm extends JvmModule - } - - trait PureCrossSbtModule extends CrossPlatformModule { - override object js extends JsModule with SbtModule - override object jvm extends JvmModule with SbtModule - } - - trait FullCrossSbtModule extends CrossPlatformModule { - trait FullSources extends JavaModule { self: PlatformModule => - override def sources = T.sources( - millSourcePath / platform / "src" / "main" / "scala", - millSourcePath / "shared" / "src" / "main" / "scala" - ) - - override def resources = T.sources( - millSourcePath / platform / "src" / "main" / "resources", - millSourcePath / "shared" / "src" / "main" / "resources" - ) - } - - override object js extends JsModule with FullSources - override object jvm extends JvmModule with FullSources - } - -} - -import support._ - -object mongo extends CommonModule { - def ivyDeps = Agg( - Deps.zio, - Deps.zioJson, - Deps.zioConfig, - ivy"org.mongodb.scala::mongo-scala-driver:4.2.3".withDottyCompat( - scalaVersion() - ) - ) -} - -object tapir extends FullCrossSbtModule { - def ivyDeps = Agg(Deps.tapirCore, Deps.tapirZIOJson, Deps.zioJson) - def jvmDeps = Agg(Deps.tapirZIO, Deps.tapirZIOHttp4sServer) - def jsDeps = Agg(Deps.tapirSttpClient) -} - -object akkaPersistence extends CommonModule { - def millSourcePath = build.millSourcePath / "akka-persistence" - def ivyDeps = (Agg( - Deps.akka.persistenceQuery, - Deps.akka.persistenceJdbc, - Deps.akka.projection.core, - Deps.akka.projection.eventsourced, - Deps.akka.projection.slick - ) ++ Deps.slick.default).map(_.withDottyCompat(scalaVersion())) ++ Agg( - Deps.zio, - Deps.zioJson, - Deps.zioConfig, - Deps.akka.persistence.withDottyCompat(scalaVersion()), - ivy"com.typesafe.akka::akka-cluster-sharding-typed:${Deps.akka.V}" - .withDottyCompat(scalaVersion()) - ) -} - -object ui extends CommonJSModule { - def ivyDeps = Agg( - Deps.zio, - Deps.laminar, - Deps.zioJson, - Deps.waypoint, - Deps.urlDsl, - Deps.laminextCore, - Deps.laminextUI, - Deps.laminextTailwind, - Deps.laminextValidationCore - ) -} diff --git a/domain.sc b/domain.sc deleted file mode 100644 index b09c56b..0000000 --- a/domain.sc +++ /dev/null @@ -1,78 +0,0 @@ -import mill._, scalalib._ - -import $file.{build => ff}, ff.support._ - -trait DomainModule extends Module { - // General extra model deps - def modelModules: Seq[Module] = Seq.empty - // General extra codecs deps - def codecsModules: Seq[Module] = Seq.empty - // General extra endpoints deps - def endpointsModules: Seq[Module] = Seq.empty - - // Implementation deps for repo - def repoModules: Seq[JavaModule] = Seq.empty - - object shared extends Module { - object model extends PureCrossModule { - def moduleDeps = modelModules - def ivyDeps = Agg(Deps.zioPrelude) - } - object codecs extends PureCrossModule { - def moduleDeps = Seq(model) ++ codecsModules - def ivyDeps = Agg(Deps.zioJson) - } - } - - trait CommonProjects extends Module { - object model extends PureCrossModule { - def ivyDeps = Agg(Deps.zioPrelude) - def moduleDeps = Seq(shared.model) - } - object codecs extends PureCrossModule { - def moduleDeps = - Seq(model, shared.model, shared.codecs, ff.tapir) - } - object endpoints extends PureCrossModule { - def ivyDeps = Agg(Deps.tapirCore, Deps.tapirZIOJson) - def moduleDeps = Seq(model, codecs) ++ endpointsModules - } - object client extends CommonJSModule { - def moduleDeps = Seq(endpoints.js) - } - object components extends CommonJSModule { - def ivyDeps = Agg( - Deps.laminar, - Deps.laminextCore, - Deps.laminextUI, - Deps.laminextTailwind, - Deps.laminextValidationCore - ) - def moduleDeps = Seq(model.js, codecs.js, client, ff.ui) - } - } - - object query extends CommonProjects { - object api extends CommonModule { - def ivyDeps = Agg(Deps.zio, Deps.tapirZIOHttp4sServer) - def moduleDeps = Seq(repo, query.endpoints.jvm) - } - object repo extends CommonModule { - def ivyDeps = Agg(Deps.zio) - def moduleDeps = Seq(model.jvm, codecs.jvm) ++ repoModules - } - object projection extends CommonModule { - def moduleDeps = Seq(repo, ff.akkaPersistence) - } - } - - object command extends CommonProjects { - object api extends CommonModule { - def ivyDeps = Agg(Deps.zio, Deps.tapirZIOHttp4sServer) - def moduleDeps = Seq(entity, command.endpoints.jvm) - } - object entity extends CommonModule { - def moduleDeps = Seq(model.jvm, codecs.jvm, ff.akkaPersistence) - } - } -} diff --git a/.sbtopts b/.sbtopts new file mode 100644 index 0000000..6913385 --- /dev/null +++ b/.sbtopts @@ -0,0 +1 @@ +-mem 2048 -J-XX:+UseG1GC diff --git a/bom.sc b/bom.sc deleted file mode 100644 index 636a511..0000000 --- a/bom.sc +++ /dev/null @@ -1,234 +0,0 @@ -import mill._, scalalib._ - -object IWMaterials { - - object Versions { - val akka = "2.6.16" - val akkaHttp = "10.2.4" - val cats = "2.7.0" - val elastic4s = "7.12.2" - val http4s = "0.23.10" - val http4sPac4J = "4.0.0" - val laminar = "0.14.2" - val laminext = laminar - val logbackClassic = "1.2.10" - val pac4j = "5.2.0" - val play = "2.8.8" - val playJson = "2.9.2" - val refined = "0.9.29" - val scalaTest = "3.2.9" - val slf4j = "1.7.36" - val slick = "3.3.3" - val sttpClient = "3.5.0" - val tapir = "0.20.1" - val urlDsl = "0.4.0" - val waypoint = "0.5.0" - val zio = "2.0.0-RC2" - val zioConfig = "3.0.0-RC2" - val zioInteropCats = "3.3.0-RC2" - val zioJson = "0.3.0-RC3" - val zioLogging = "2.0.0-RC5" - val zioPrelude = "1.0.0-RC10" - val zioZMX = "0.0.11" - } - - object Deps extends AkkaLibs with SlickLibs { - import IWMaterials.{Versions => V} - - val zioOrg = "dev.zio" - - def zioLib(name: String, version: String): Dep = - ivy"$zioOrg::zio-$name::$version" - - lazy val zio: Dep = ivy"$zioOrg::zio:${V.zio}" - - lazy val zioTest: Dep = zioLib("test", V.zio) - lazy val zioTestSbt: Dep = zioLib("test-sbt", V.zio) - - lazy val zioConfig: Dep = zioLib("config", V.zioConfig) - lazy val zioConfigTypesafe: Dep = - zioLib("config-typesafe", V.zioConfig) - lazy val zioConfigMagnolia: Dep = - zioLib("config-magnolia", V.zioConfig) - - lazy val zioJson: Dep = zioLib("json", V.zioJson) - lazy val zioLogging: Dep = zioLib("logging", V.zioLogging) - lazy val zioLoggingSlf4j: Dep = - zioLib("logging-slf4j", V.zioLogging) - lazy val zioPrelude: Dep = zioLib("prelude", V.zioPrelude) - lazy val zioStreams: Dep = zioLib("streams", V.zio) - lazy val zioZMX: Dep = zioLib("zmx", V.zioZMX) - lazy val zioInteropCats: Dep = - zioLib("interop-cats", V.zioInteropCats) - - lazy val catsCore: Dep = ivy"org.typelevel::cats-core::${V.cats}" - - lazy val refined: Dep = ivy"eu.timepit::refined::${V.refined}" - - /* What is the equivalent? ZIOModule with prepared test config? - def useZIO(testConf: Configuration*): Agg[Dep] = Agg( - zio, - zioTest, - zioTestSbt, - testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework") - ) - */ - - /* - def useZIOAll(testConf: Configuration*): Seq[Def.Setting[_]] = - useZIO(testConf: _*) ++ Seq( - zioStreams, - zioConfig, - zioConfigTypesafe, - zioConfigMagnolia, - zioJson, - zioZMX, - zioLogging, - zioPrelude - ) - */ - - private val tapirOrg = "com.softwaremill.sttp.tapir" - def tapirLib(name: String): Dep = - ivy"${tapirOrg}::tapir-$name::${V.tapir}" - - lazy val tapirCore: Dep = tapirLib("core") - lazy val tapirZIO: Dep = tapirLib("zio") - lazy val tapirZIOJson: Dep = tapirLib("json-zio") - lazy val tapirSttpClient: Dep = tapirLib("sttp-client") - lazy val tapirCats: Dep = tapirLib("cats") - lazy val tapirZIOHttp4sServer: Dep = tapirLib("zio-http4s-server") - - val sttpClientOrg = "com.softwaremill.sttp.client3" - def sttpClientLib(name: String): Dep = - 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}" - - lazy val http4sPac4J: Dep = - ivy"org.pac4j::http4s-pac4j:${V.http4sPac4J}" - lazy val pac4jOIDC: Dep = - ivy"org.pac4j:pac4j-oidc:${V.pac4j}" - - lazy val scalaTest: Dep = - ivy"org.scalatest::scalatest:${V.scalaTest}" - lazy val scalaTestPlusScalacheck: Dep = - ivy"org.scalatestplus::scalacheck-1-15:3.2.9.0" - lazy val playScalaTest: Dep = - ivy"org.scalatestplus.play::scalatestplus-play:5.1.0" - - private val playOrg = "com.typesafe.play" - lazy val playMailer: Dep = ivy"${playOrg}::play-mailer:8.0.1" - lazy val playServer: Dep = ivy"${playOrg}::play-server:${V.play}" - lazy val playAkkaServer: Dep = - ivy"${playOrg}::play-akka-http-server:${V.play}" - lazy val play: Dep = ivy"${playOrg}::play:${V.play}" - lazy val playAhcWs: Dep = ivy"${playOrg}::play-ahc-ws:${V.play}" - lazy val playJson: Dep = ivy"${playOrg}::play-json:${V.playJson}" - - private val elastic4sOrg = "com.sksamuel.elastic4s" - lazy val useElastic4S: Agg[Dep] = Agg( - ivy"${elastic4sOrg}::elastic4s-core:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-client-akka:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-http-streams:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-json-play:${V.elastic4s}" - ) - - lazy val laminar: Dep = ivy"com.raquo::laminar::${V.laminar}" - - private def laminext(name: String): Dep = - ivy"io.laminext::$name::${V.laminar}" - - lazy val laminextCore: Dep = laminext("core") - lazy val laminextTailwind: Dep = laminext("tailwind") - lazy val laminextFetch: Dep = laminext("fetch") - lazy val laminextValidationCore: Dep = laminext("validation-core") - lazy val laminextUI: Dep = laminext("ui") - - lazy val waypoint: Dep = - ivy"com.raquo::waypoint::${V.waypoint}" - - lazy val urlDsl: Dep = - ivy"be.doeraene::url-dsl::${V.urlDsl}" - - lazy val scalaJavaTime: Dep = - ivy"io.github.cquiroz::scala-java-time::2.3.0" - - lazy val scalaJavaLocales: Dep = - ivy"io.github.cquiroz::scala-java-locales::1.2.1" - - lazy val logbackClassic: Dep = - ivy"ch.qos.logback:logback-classic:${V.logbackClassic}" - } - - trait AkkaLibs { - - self: SlickLibs => - - object akka { - val V = Versions.akka - val tOrg = "com.typesafe.akka" - val lOrg = "com.lightbend.akka" - - def akkaMod(name: String): Dep = - ivy"$tOrg::akka-$name:$V" - - lazy val actor: Dep = akkaMod("actor") - lazy val actorTyped: Dep = akkaMod("actor-typed") - lazy val stream: Dep = akkaMod("stream") - lazy val persistence: Dep = akkaMod("persistence-typed") - lazy val persistenceQuery: Dep = akkaMod("persistence-query") - lazy val persistenceJdbc: Dep = - ivy"$lOrg::akka-persistence-jdbc:5.0.4" - val persistenceTestKit: Dep = ivy"$tOrg::akka-persistence-testkit:$V" - - object http { - val V = Versions.akkaHttp - - lazy val http: Dep = ivy"$tOrg::akka-http:$V" - lazy val sprayJson: Dep = ivy"$tOrg::akka-http-spray-json:$V" - - } - - object projection { - val V = "1.2.2" - - lazy val core: Dep = - ivy"$lOrg::akka-projection-core:$V" - lazy val eventsourced: Dep = - ivy"$lOrg::akka-projection-eventsourced:$V" - lazy val slick: Dep = - ivy"$lOrg::akka-projection-slick:$V" - lazy val jdbc: Dep = - ivy"$lOrg::akka-projection-jdbc:$V" - } - - object profiles { - // TODO: deal with cross-version for Scala3 (for3Use2_13) - lazy val eventsourcedJdbcProjection: Agg[Dep] = Agg( - persistenceQuery, - projection.core, - projection.eventsourced, - projection.slick, - persistenceJdbc - ) ++ slick.default - } - } - } - - trait SlickLibs { - object slick { - val V = IWMaterials.Versions.slick - val org = "com.typesafe.slick" - - lazy val slick: Dep = ivy"$org::slick:$V" - lazy val hikaricp: Dep = ivy"$org::slick-hikaricp:$V" - lazy val default: Agg[Dep] = Agg(slick, hikaricp) - } - } - -} diff --git a/build.sbt b/build.sbt new file mode 100644 index 0000000..a8bc367 --- /dev/null +++ b/build.sbt @@ -0,0 +1,123 @@ +ThisBuild / scalaVersion := scala3Version + +publishToIW + +lazy val core = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .settings(name := "iw-support-core") + .in(file("core")) + .settings(IWDeps.zioPrelude) + +lazy val `tapir-support` = crossProject(JSPlatform, JVMPlatform) + .in(file("tapir")) + .settings(name := "iw-support-tapir") + .settings( + IWDeps.tapirCore, + IWDeps.tapirZIOJson, + IWDeps.useZIOJson, + IWDeps.tapirSttpClient + ) + .jvmSettings( + IWDeps.tapirZIO, + IWDeps.tapirZIOHttp4sServer, + IWDeps.useZIOJson, + IWDeps.sttpClientLib("async-http-client-backend-zio"), + IWDeps.zioLib("interop-reactivestreams", "2.0.0"), + IWDeps.zioLib("nio", "2.0.0"), + excludeDependencies += // Gets transitively dragged in by zio-nio, conflicting with _3 + ExclusionRule("org.scala-lang.modules", "scala-collection-compat_2.13") + ) + +lazy val codecs = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .in(file("codecs")) + .settings(name := "iw-support-codecs") + .settings( + IWDeps.useZIOJson, + excludeDependencies += // Gets transitively dragged in by zio-nio, conflicting with _3 + ExclusionRule("org.scala-lang.modules", "scala-collection-compat_2.13") + ) + .dependsOn(core, `tapir-support`) + +lazy val `mongo-support` = project + .in(file("mongo")) + .configs(IntegrationTest) + .settings(name := "iw-support-mongo") + .settings( + Defaults.itSettings, + IWDeps.useZIO(Test, IntegrationTest), + IWDeps.useZIOJson, + IWDeps.zioConfig, + libraryDependencies += ("org.mongodb.scala" %% "mongo-scala-driver" % "4.2.3") + .cross(CrossVersion.for3Use2_13) + ) + +lazy val `akka-persistence-support` = project + .in(file("akka-persistence")) + .settings(name := "iw-support-akka-persistence") + .settings( + IWDeps.useZIO(Test), + IWDeps.useZIOJson, + IWDeps.zioConfig, + libraryDependencies += IWDeps.akka.modules.persistence + .cross(CrossVersion.for3Use2_13), + libraryDependencies += "com.typesafe.akka" %% "akka-cluster-sharding-typed" % IWDeps.akka.V cross (CrossVersion.for3Use2_13), + IWDeps.akka.profiles.eventsourcedJdbcProjection + ) + +lazy val ui = (project in file("ui")) + .enablePlugins(ScalaJSPlugin) + .settings(name := "iw-support-ui") + .settings( + IWDeps.useZIO(Test), + IWDeps.laminar, + IWDeps.useZIOJson, + IWDeps.waypoint, + IWDeps.urlDsl, + IWDeps.laminextCore, + IWDeps.laminextUI, + IWDeps.laminextTailwind, + IWDeps.laminextValidationCore + ) + +lazy val `ui-model` = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .in(file("ui/model")) + .settings(name := "iw-support-ui-model") + .dependsOn(core) + +lazy val `ui-components` = (project in file("ui/components")) + .enablePlugins(ScalaJSPlugin) + .settings(name := "iw-support-ui-components") + .settings( + IWDeps.useZIO(Test), + IWDeps.zioPrelude, + IWDeps.laminar, + IWDeps.useZIOJson, + IWDeps.waypoint, + IWDeps.urlDsl, + IWDeps.laminextCore, + IWDeps.laminextUI, + IWDeps.laminextTailwind, + IWDeps.laminextValidationCore + ) + .dependsOn(`ui-model`.js) + +lazy val root = (project in file(".")) + .settings(name := "iw-support", publish / skip := true) + // Auto activates for all projects, but make sure we have required dependencies + .enablePlugins(IWScalaProjectPlugin, GitVersioning) + .aggregate( + core.js, + core.jvm, + codecs.js, + codecs.jvm, + `tapir-support`.js, + `tapir-support`.jvm, + `mongo-support`, + `akka-persistence-support`, + ui, + `ui-model`.js, + `ui-model`.jvm, + `ui-components` + ) diff --git a/build.sc b/build.sc deleted file mode 100644 index 3f3da4f..0000000 --- a/build.sc +++ /dev/null @@ -1,146 +0,0 @@ -import mill._, scalalib._, scalajslib._ - -import $file.bom - -object support { - val Deps = bom.IWMaterials.Deps - val Versions = bom.IWMaterials.Versions - - trait CommonModule extends ScalaModule { - def scalaVersion = "3.1.1" - def scalacOptions = T { - super.scalacOptions() ++ Seq( - "-encoding", - "utf8", - "-deprecation", - "-explain-types", - "-explain", - "-feature", - "-language:experimental.macros", - "-language:higherKinds", - "-language:implicitConversions", - "-unchecked", - "-Xfatal-warnings", - "-Ykind-projector" - ) - } - } - - trait CommonJSModule extends CommonModule with ScalaJSModule { - def scalaJSVersion = "1.9.0" - } - - trait CrossPlatformModule extends Module { outer => - def ivyDeps: T[Agg[Dep]] = Agg[Dep]() - def jsDeps: T[Agg[Dep]] = Agg[Dep]() - def jvmDeps: T[Agg[Dep]] = Agg[Dep]() - def moduleDeps: Seq[Module] = Seq[Module]() - - trait PlatformModule extends CommonModule { - def platform: String - override def millSourcePath = outer.millSourcePath - override def ivyDeps = outer.ivyDeps() ++ (platform match { - case "js" => jsDeps() - case _ => jvmDeps() - }) - override def moduleDeps = outer.moduleDeps.collect { - case m: CrossPlatformModule => - platform match { - case "js" => m.js - case _ => m.jvm - } - case m: JavaModule => m - } - } - - trait JsModule extends PlatformModule with CommonJSModule { - def platform = "js" - } - - trait JvmModule extends PlatformModule { - def platform = "jvm" - } - - val js: JsModule - val jvm: JvmModule - } - - trait PureCrossModule extends CrossPlatformModule { - override object js extends JsModule - override object jvm extends JvmModule - } - - trait PureCrossSbtModule extends CrossPlatformModule { - override object js extends JsModule with SbtModule - override object jvm extends JvmModule with SbtModule - } - - trait FullCrossSbtModule extends CrossPlatformModule { - trait FullSources extends JavaModule { self: PlatformModule => - override def sources = T.sources( - millSourcePath / platform / "src" / "main" / "scala", - millSourcePath / "shared" / "src" / "main" / "scala" - ) - - override def resources = T.sources( - millSourcePath / platform / "src" / "main" / "resources", - millSourcePath / "shared" / "src" / "main" / "resources" - ) - } - - override object js extends JsModule with FullSources - override object jvm extends JvmModule with FullSources - } - -} - -import support._ - -object mongo extends CommonModule { - def ivyDeps = Agg( - Deps.zio, - Deps.zioJson, - Deps.zioConfig, - ivy"org.mongodb.scala::mongo-scala-driver:4.2.3".withDottyCompat( - scalaVersion() - ) - ) -} - -object tapir extends FullCrossSbtModule { - def ivyDeps = Agg(Deps.tapirCore, Deps.tapirZIOJson, Deps.zioJson) - def jvmDeps = Agg(Deps.tapirZIO, Deps.tapirZIOHttp4sServer) - def jsDeps = Agg(Deps.tapirSttpClient) -} - -object akkaPersistence extends CommonModule { - def millSourcePath = build.millSourcePath / "akka-persistence" - def ivyDeps = (Agg( - Deps.akka.persistenceQuery, - Deps.akka.persistenceJdbc, - Deps.akka.projection.core, - Deps.akka.projection.eventsourced, - Deps.akka.projection.slick - ) ++ Deps.slick.default).map(_.withDottyCompat(scalaVersion())) ++ Agg( - Deps.zio, - Deps.zioJson, - Deps.zioConfig, - Deps.akka.persistence.withDottyCompat(scalaVersion()), - ivy"com.typesafe.akka::akka-cluster-sharding-typed:${Deps.akka.V}" - .withDottyCompat(scalaVersion()) - ) -} - -object ui extends CommonJSModule { - def ivyDeps = Agg( - Deps.zio, - Deps.laminar, - Deps.zioJson, - Deps.waypoint, - Deps.urlDsl, - Deps.laminextCore, - Deps.laminextUI, - Deps.laminextTailwind, - Deps.laminextValidationCore - ) -} diff --git a/domain.sc b/domain.sc deleted file mode 100644 index b09c56b..0000000 --- a/domain.sc +++ /dev/null @@ -1,78 +0,0 @@ -import mill._, scalalib._ - -import $file.{build => ff}, ff.support._ - -trait DomainModule extends Module { - // General extra model deps - def modelModules: Seq[Module] = Seq.empty - // General extra codecs deps - def codecsModules: Seq[Module] = Seq.empty - // General extra endpoints deps - def endpointsModules: Seq[Module] = Seq.empty - - // Implementation deps for repo - def repoModules: Seq[JavaModule] = Seq.empty - - object shared extends Module { - object model extends PureCrossModule { - def moduleDeps = modelModules - def ivyDeps = Agg(Deps.zioPrelude) - } - object codecs extends PureCrossModule { - def moduleDeps = Seq(model) ++ codecsModules - def ivyDeps = Agg(Deps.zioJson) - } - } - - trait CommonProjects extends Module { - object model extends PureCrossModule { - def ivyDeps = Agg(Deps.zioPrelude) - def moduleDeps = Seq(shared.model) - } - object codecs extends PureCrossModule { - def moduleDeps = - Seq(model, shared.model, shared.codecs, ff.tapir) - } - object endpoints extends PureCrossModule { - def ivyDeps = Agg(Deps.tapirCore, Deps.tapirZIOJson) - def moduleDeps = Seq(model, codecs) ++ endpointsModules - } - object client extends CommonJSModule { - def moduleDeps = Seq(endpoints.js) - } - object components extends CommonJSModule { - def ivyDeps = Agg( - Deps.laminar, - Deps.laminextCore, - Deps.laminextUI, - Deps.laminextTailwind, - Deps.laminextValidationCore - ) - def moduleDeps = Seq(model.js, codecs.js, client, ff.ui) - } - } - - object query extends CommonProjects { - object api extends CommonModule { - def ivyDeps = Agg(Deps.zio, Deps.tapirZIOHttp4sServer) - def moduleDeps = Seq(repo, query.endpoints.jvm) - } - object repo extends CommonModule { - def ivyDeps = Agg(Deps.zio) - def moduleDeps = Seq(model.jvm, codecs.jvm) ++ repoModules - } - object projection extends CommonModule { - def moduleDeps = Seq(repo, ff.akkaPersistence) - } - } - - object command extends CommonProjects { - object api extends CommonModule { - def ivyDeps = Agg(Deps.zio, Deps.tapirZIOHttp4sServer) - def moduleDeps = Seq(entity, command.endpoints.jvm) - } - object entity extends CommonModule { - def moduleDeps = Seq(model.jvm, codecs.jvm, ff.akkaPersistence) - } - } -} diff --git a/mongo/src/it/scala/works/iterative/mongo/MongoJsonFileRepositoryIntegrationSpec.scala b/mongo/src/it/scala/works/iterative/mongo/MongoJsonFileRepositoryIntegrationSpec.scala index eed0e73..f432251 100644 --- a/mongo/src/it/scala/works/iterative/mongo/MongoJsonFileRepositoryIntegrationSpec.scala +++ b/mongo/src/it/scala/works/iterative/mongo/MongoJsonFileRepositoryIntegrationSpec.scala @@ -27,9 +27,10 @@ result <- repo.matching(ByOsobniCislo("10123")) yield assertTrue(result.head.name == fname) ) - ).provideCustomLayer(layer.mapError(TestFailure.fail)) + ).provide(layer) @@ TestAspect.ifEnvSet("MONGO_URI") - val layer = + val layer + : TaskLayer[MongoJsonFileRepository[ExampleMetadata, ExampleCriteria]] = import org.mongodb.scala.* import org.mongodb.scala.model.Filters.* import org.bson.json.JsonObject diff --git a/.sbtopts b/.sbtopts new file mode 100644 index 0000000..6913385 --- /dev/null +++ b/.sbtopts @@ -0,0 +1 @@ +-mem 2048 -J-XX:+UseG1GC diff --git a/bom.sc b/bom.sc deleted file mode 100644 index 636a511..0000000 --- a/bom.sc +++ /dev/null @@ -1,234 +0,0 @@ -import mill._, scalalib._ - -object IWMaterials { - - object Versions { - val akka = "2.6.16" - val akkaHttp = "10.2.4" - val cats = "2.7.0" - val elastic4s = "7.12.2" - val http4s = "0.23.10" - val http4sPac4J = "4.0.0" - val laminar = "0.14.2" - val laminext = laminar - val logbackClassic = "1.2.10" - val pac4j = "5.2.0" - val play = "2.8.8" - val playJson = "2.9.2" - val refined = "0.9.29" - val scalaTest = "3.2.9" - val slf4j = "1.7.36" - val slick = "3.3.3" - val sttpClient = "3.5.0" - val tapir = "0.20.1" - val urlDsl = "0.4.0" - val waypoint = "0.5.0" - val zio = "2.0.0-RC2" - val zioConfig = "3.0.0-RC2" - val zioInteropCats = "3.3.0-RC2" - val zioJson = "0.3.0-RC3" - val zioLogging = "2.0.0-RC5" - val zioPrelude = "1.0.0-RC10" - val zioZMX = "0.0.11" - } - - object Deps extends AkkaLibs with SlickLibs { - import IWMaterials.{Versions => V} - - val zioOrg = "dev.zio" - - def zioLib(name: String, version: String): Dep = - ivy"$zioOrg::zio-$name::$version" - - lazy val zio: Dep = ivy"$zioOrg::zio:${V.zio}" - - lazy val zioTest: Dep = zioLib("test", V.zio) - lazy val zioTestSbt: Dep = zioLib("test-sbt", V.zio) - - lazy val zioConfig: Dep = zioLib("config", V.zioConfig) - lazy val zioConfigTypesafe: Dep = - zioLib("config-typesafe", V.zioConfig) - lazy val zioConfigMagnolia: Dep = - zioLib("config-magnolia", V.zioConfig) - - lazy val zioJson: Dep = zioLib("json", V.zioJson) - lazy val zioLogging: Dep = zioLib("logging", V.zioLogging) - lazy val zioLoggingSlf4j: Dep = - zioLib("logging-slf4j", V.zioLogging) - lazy val zioPrelude: Dep = zioLib("prelude", V.zioPrelude) - lazy val zioStreams: Dep = zioLib("streams", V.zio) - lazy val zioZMX: Dep = zioLib("zmx", V.zioZMX) - lazy val zioInteropCats: Dep = - zioLib("interop-cats", V.zioInteropCats) - - lazy val catsCore: Dep = ivy"org.typelevel::cats-core::${V.cats}" - - lazy val refined: Dep = ivy"eu.timepit::refined::${V.refined}" - - /* What is the equivalent? ZIOModule with prepared test config? - def useZIO(testConf: Configuration*): Agg[Dep] = Agg( - zio, - zioTest, - zioTestSbt, - testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework") - ) - */ - - /* - def useZIOAll(testConf: Configuration*): Seq[Def.Setting[_]] = - useZIO(testConf: _*) ++ Seq( - zioStreams, - zioConfig, - zioConfigTypesafe, - zioConfigMagnolia, - zioJson, - zioZMX, - zioLogging, - zioPrelude - ) - */ - - private val tapirOrg = "com.softwaremill.sttp.tapir" - def tapirLib(name: String): Dep = - ivy"${tapirOrg}::tapir-$name::${V.tapir}" - - lazy val tapirCore: Dep = tapirLib("core") - lazy val tapirZIO: Dep = tapirLib("zio") - lazy val tapirZIOJson: Dep = tapirLib("json-zio") - lazy val tapirSttpClient: Dep = tapirLib("sttp-client") - lazy val tapirCats: Dep = tapirLib("cats") - lazy val tapirZIOHttp4sServer: Dep = tapirLib("zio-http4s-server") - - val sttpClientOrg = "com.softwaremill.sttp.client3" - def sttpClientLib(name: String): Dep = - 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}" - - lazy val http4sPac4J: Dep = - ivy"org.pac4j::http4s-pac4j:${V.http4sPac4J}" - lazy val pac4jOIDC: Dep = - ivy"org.pac4j:pac4j-oidc:${V.pac4j}" - - lazy val scalaTest: Dep = - ivy"org.scalatest::scalatest:${V.scalaTest}" - lazy val scalaTestPlusScalacheck: Dep = - ivy"org.scalatestplus::scalacheck-1-15:3.2.9.0" - lazy val playScalaTest: Dep = - ivy"org.scalatestplus.play::scalatestplus-play:5.1.0" - - private val playOrg = "com.typesafe.play" - lazy val playMailer: Dep = ivy"${playOrg}::play-mailer:8.0.1" - lazy val playServer: Dep = ivy"${playOrg}::play-server:${V.play}" - lazy val playAkkaServer: Dep = - ivy"${playOrg}::play-akka-http-server:${V.play}" - lazy val play: Dep = ivy"${playOrg}::play:${V.play}" - lazy val playAhcWs: Dep = ivy"${playOrg}::play-ahc-ws:${V.play}" - lazy val playJson: Dep = ivy"${playOrg}::play-json:${V.playJson}" - - private val elastic4sOrg = "com.sksamuel.elastic4s" - lazy val useElastic4S: Agg[Dep] = Agg( - ivy"${elastic4sOrg}::elastic4s-core:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-client-akka:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-http-streams:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-json-play:${V.elastic4s}" - ) - - lazy val laminar: Dep = ivy"com.raquo::laminar::${V.laminar}" - - private def laminext(name: String): Dep = - ivy"io.laminext::$name::${V.laminar}" - - lazy val laminextCore: Dep = laminext("core") - lazy val laminextTailwind: Dep = laminext("tailwind") - lazy val laminextFetch: Dep = laminext("fetch") - lazy val laminextValidationCore: Dep = laminext("validation-core") - lazy val laminextUI: Dep = laminext("ui") - - lazy val waypoint: Dep = - ivy"com.raquo::waypoint::${V.waypoint}" - - lazy val urlDsl: Dep = - ivy"be.doeraene::url-dsl::${V.urlDsl}" - - lazy val scalaJavaTime: Dep = - ivy"io.github.cquiroz::scala-java-time::2.3.0" - - lazy val scalaJavaLocales: Dep = - ivy"io.github.cquiroz::scala-java-locales::1.2.1" - - lazy val logbackClassic: Dep = - ivy"ch.qos.logback:logback-classic:${V.logbackClassic}" - } - - trait AkkaLibs { - - self: SlickLibs => - - object akka { - val V = Versions.akka - val tOrg = "com.typesafe.akka" - val lOrg = "com.lightbend.akka" - - def akkaMod(name: String): Dep = - ivy"$tOrg::akka-$name:$V" - - lazy val actor: Dep = akkaMod("actor") - lazy val actorTyped: Dep = akkaMod("actor-typed") - lazy val stream: Dep = akkaMod("stream") - lazy val persistence: Dep = akkaMod("persistence-typed") - lazy val persistenceQuery: Dep = akkaMod("persistence-query") - lazy val persistenceJdbc: Dep = - ivy"$lOrg::akka-persistence-jdbc:5.0.4" - val persistenceTestKit: Dep = ivy"$tOrg::akka-persistence-testkit:$V" - - object http { - val V = Versions.akkaHttp - - lazy val http: Dep = ivy"$tOrg::akka-http:$V" - lazy val sprayJson: Dep = ivy"$tOrg::akka-http-spray-json:$V" - - } - - object projection { - val V = "1.2.2" - - lazy val core: Dep = - ivy"$lOrg::akka-projection-core:$V" - lazy val eventsourced: Dep = - ivy"$lOrg::akka-projection-eventsourced:$V" - lazy val slick: Dep = - ivy"$lOrg::akka-projection-slick:$V" - lazy val jdbc: Dep = - ivy"$lOrg::akka-projection-jdbc:$V" - } - - object profiles { - // TODO: deal with cross-version for Scala3 (for3Use2_13) - lazy val eventsourcedJdbcProjection: Agg[Dep] = Agg( - persistenceQuery, - projection.core, - projection.eventsourced, - projection.slick, - persistenceJdbc - ) ++ slick.default - } - } - } - - trait SlickLibs { - object slick { - val V = IWMaterials.Versions.slick - val org = "com.typesafe.slick" - - lazy val slick: Dep = ivy"$org::slick:$V" - lazy val hikaricp: Dep = ivy"$org::slick-hikaricp:$V" - lazy val default: Agg[Dep] = Agg(slick, hikaricp) - } - } - -} diff --git a/build.sbt b/build.sbt new file mode 100644 index 0000000..a8bc367 --- /dev/null +++ b/build.sbt @@ -0,0 +1,123 @@ +ThisBuild / scalaVersion := scala3Version + +publishToIW + +lazy val core = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .settings(name := "iw-support-core") + .in(file("core")) + .settings(IWDeps.zioPrelude) + +lazy val `tapir-support` = crossProject(JSPlatform, JVMPlatform) + .in(file("tapir")) + .settings(name := "iw-support-tapir") + .settings( + IWDeps.tapirCore, + IWDeps.tapirZIOJson, + IWDeps.useZIOJson, + IWDeps.tapirSttpClient + ) + .jvmSettings( + IWDeps.tapirZIO, + IWDeps.tapirZIOHttp4sServer, + IWDeps.useZIOJson, + IWDeps.sttpClientLib("async-http-client-backend-zio"), + IWDeps.zioLib("interop-reactivestreams", "2.0.0"), + IWDeps.zioLib("nio", "2.0.0"), + excludeDependencies += // Gets transitively dragged in by zio-nio, conflicting with _3 + ExclusionRule("org.scala-lang.modules", "scala-collection-compat_2.13") + ) + +lazy val codecs = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .in(file("codecs")) + .settings(name := "iw-support-codecs") + .settings( + IWDeps.useZIOJson, + excludeDependencies += // Gets transitively dragged in by zio-nio, conflicting with _3 + ExclusionRule("org.scala-lang.modules", "scala-collection-compat_2.13") + ) + .dependsOn(core, `tapir-support`) + +lazy val `mongo-support` = project + .in(file("mongo")) + .configs(IntegrationTest) + .settings(name := "iw-support-mongo") + .settings( + Defaults.itSettings, + IWDeps.useZIO(Test, IntegrationTest), + IWDeps.useZIOJson, + IWDeps.zioConfig, + libraryDependencies += ("org.mongodb.scala" %% "mongo-scala-driver" % "4.2.3") + .cross(CrossVersion.for3Use2_13) + ) + +lazy val `akka-persistence-support` = project + .in(file("akka-persistence")) + .settings(name := "iw-support-akka-persistence") + .settings( + IWDeps.useZIO(Test), + IWDeps.useZIOJson, + IWDeps.zioConfig, + libraryDependencies += IWDeps.akka.modules.persistence + .cross(CrossVersion.for3Use2_13), + libraryDependencies += "com.typesafe.akka" %% "akka-cluster-sharding-typed" % IWDeps.akka.V cross (CrossVersion.for3Use2_13), + IWDeps.akka.profiles.eventsourcedJdbcProjection + ) + +lazy val ui = (project in file("ui")) + .enablePlugins(ScalaJSPlugin) + .settings(name := "iw-support-ui") + .settings( + IWDeps.useZIO(Test), + IWDeps.laminar, + IWDeps.useZIOJson, + IWDeps.waypoint, + IWDeps.urlDsl, + IWDeps.laminextCore, + IWDeps.laminextUI, + IWDeps.laminextTailwind, + IWDeps.laminextValidationCore + ) + +lazy val `ui-model` = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .in(file("ui/model")) + .settings(name := "iw-support-ui-model") + .dependsOn(core) + +lazy val `ui-components` = (project in file("ui/components")) + .enablePlugins(ScalaJSPlugin) + .settings(name := "iw-support-ui-components") + .settings( + IWDeps.useZIO(Test), + IWDeps.zioPrelude, + IWDeps.laminar, + IWDeps.useZIOJson, + IWDeps.waypoint, + IWDeps.urlDsl, + IWDeps.laminextCore, + IWDeps.laminextUI, + IWDeps.laminextTailwind, + IWDeps.laminextValidationCore + ) + .dependsOn(`ui-model`.js) + +lazy val root = (project in file(".")) + .settings(name := "iw-support", publish / skip := true) + // Auto activates for all projects, but make sure we have required dependencies + .enablePlugins(IWScalaProjectPlugin, GitVersioning) + .aggregate( + core.js, + core.jvm, + codecs.js, + codecs.jvm, + `tapir-support`.js, + `tapir-support`.jvm, + `mongo-support`, + `akka-persistence-support`, + ui, + `ui-model`.js, + `ui-model`.jvm, + `ui-components` + ) diff --git a/build.sc b/build.sc deleted file mode 100644 index 3f3da4f..0000000 --- a/build.sc +++ /dev/null @@ -1,146 +0,0 @@ -import mill._, scalalib._, scalajslib._ - -import $file.bom - -object support { - val Deps = bom.IWMaterials.Deps - val Versions = bom.IWMaterials.Versions - - trait CommonModule extends ScalaModule { - def scalaVersion = "3.1.1" - def scalacOptions = T { - super.scalacOptions() ++ Seq( - "-encoding", - "utf8", - "-deprecation", - "-explain-types", - "-explain", - "-feature", - "-language:experimental.macros", - "-language:higherKinds", - "-language:implicitConversions", - "-unchecked", - "-Xfatal-warnings", - "-Ykind-projector" - ) - } - } - - trait CommonJSModule extends CommonModule with ScalaJSModule { - def scalaJSVersion = "1.9.0" - } - - trait CrossPlatformModule extends Module { outer => - def ivyDeps: T[Agg[Dep]] = Agg[Dep]() - def jsDeps: T[Agg[Dep]] = Agg[Dep]() - def jvmDeps: T[Agg[Dep]] = Agg[Dep]() - def moduleDeps: Seq[Module] = Seq[Module]() - - trait PlatformModule extends CommonModule { - def platform: String - override def millSourcePath = outer.millSourcePath - override def ivyDeps = outer.ivyDeps() ++ (platform match { - case "js" => jsDeps() - case _ => jvmDeps() - }) - override def moduleDeps = outer.moduleDeps.collect { - case m: CrossPlatformModule => - platform match { - case "js" => m.js - case _ => m.jvm - } - case m: JavaModule => m - } - } - - trait JsModule extends PlatformModule with CommonJSModule { - def platform = "js" - } - - trait JvmModule extends PlatformModule { - def platform = "jvm" - } - - val js: JsModule - val jvm: JvmModule - } - - trait PureCrossModule extends CrossPlatformModule { - override object js extends JsModule - override object jvm extends JvmModule - } - - trait PureCrossSbtModule extends CrossPlatformModule { - override object js extends JsModule with SbtModule - override object jvm extends JvmModule with SbtModule - } - - trait FullCrossSbtModule extends CrossPlatformModule { - trait FullSources extends JavaModule { self: PlatformModule => - override def sources = T.sources( - millSourcePath / platform / "src" / "main" / "scala", - millSourcePath / "shared" / "src" / "main" / "scala" - ) - - override def resources = T.sources( - millSourcePath / platform / "src" / "main" / "resources", - millSourcePath / "shared" / "src" / "main" / "resources" - ) - } - - override object js extends JsModule with FullSources - override object jvm extends JvmModule with FullSources - } - -} - -import support._ - -object mongo extends CommonModule { - def ivyDeps = Agg( - Deps.zio, - Deps.zioJson, - Deps.zioConfig, - ivy"org.mongodb.scala::mongo-scala-driver:4.2.3".withDottyCompat( - scalaVersion() - ) - ) -} - -object tapir extends FullCrossSbtModule { - def ivyDeps = Agg(Deps.tapirCore, Deps.tapirZIOJson, Deps.zioJson) - def jvmDeps = Agg(Deps.tapirZIO, Deps.tapirZIOHttp4sServer) - def jsDeps = Agg(Deps.tapirSttpClient) -} - -object akkaPersistence extends CommonModule { - def millSourcePath = build.millSourcePath / "akka-persistence" - def ivyDeps = (Agg( - Deps.akka.persistenceQuery, - Deps.akka.persistenceJdbc, - Deps.akka.projection.core, - Deps.akka.projection.eventsourced, - Deps.akka.projection.slick - ) ++ Deps.slick.default).map(_.withDottyCompat(scalaVersion())) ++ Agg( - Deps.zio, - Deps.zioJson, - Deps.zioConfig, - Deps.akka.persistence.withDottyCompat(scalaVersion()), - ivy"com.typesafe.akka::akka-cluster-sharding-typed:${Deps.akka.V}" - .withDottyCompat(scalaVersion()) - ) -} - -object ui extends CommonJSModule { - def ivyDeps = Agg( - Deps.zio, - Deps.laminar, - Deps.zioJson, - Deps.waypoint, - Deps.urlDsl, - Deps.laminextCore, - Deps.laminextUI, - Deps.laminextTailwind, - Deps.laminextValidationCore - ) -} diff --git a/domain.sc b/domain.sc deleted file mode 100644 index b09c56b..0000000 --- a/domain.sc +++ /dev/null @@ -1,78 +0,0 @@ -import mill._, scalalib._ - -import $file.{build => ff}, ff.support._ - -trait DomainModule extends Module { - // General extra model deps - def modelModules: Seq[Module] = Seq.empty - // General extra codecs deps - def codecsModules: Seq[Module] = Seq.empty - // General extra endpoints deps - def endpointsModules: Seq[Module] = Seq.empty - - // Implementation deps for repo - def repoModules: Seq[JavaModule] = Seq.empty - - object shared extends Module { - object model extends PureCrossModule { - def moduleDeps = modelModules - def ivyDeps = Agg(Deps.zioPrelude) - } - object codecs extends PureCrossModule { - def moduleDeps = Seq(model) ++ codecsModules - def ivyDeps = Agg(Deps.zioJson) - } - } - - trait CommonProjects extends Module { - object model extends PureCrossModule { - def ivyDeps = Agg(Deps.zioPrelude) - def moduleDeps = Seq(shared.model) - } - object codecs extends PureCrossModule { - def moduleDeps = - Seq(model, shared.model, shared.codecs, ff.tapir) - } - object endpoints extends PureCrossModule { - def ivyDeps = Agg(Deps.tapirCore, Deps.tapirZIOJson) - def moduleDeps = Seq(model, codecs) ++ endpointsModules - } - object client extends CommonJSModule { - def moduleDeps = Seq(endpoints.js) - } - object components extends CommonJSModule { - def ivyDeps = Agg( - Deps.laminar, - Deps.laminextCore, - Deps.laminextUI, - Deps.laminextTailwind, - Deps.laminextValidationCore - ) - def moduleDeps = Seq(model.js, codecs.js, client, ff.ui) - } - } - - object query extends CommonProjects { - object api extends CommonModule { - def ivyDeps = Agg(Deps.zio, Deps.tapirZIOHttp4sServer) - def moduleDeps = Seq(repo, query.endpoints.jvm) - } - object repo extends CommonModule { - def ivyDeps = Agg(Deps.zio) - def moduleDeps = Seq(model.jvm, codecs.jvm) ++ repoModules - } - object projection extends CommonModule { - def moduleDeps = Seq(repo, ff.akkaPersistence) - } - } - - object command extends CommonProjects { - object api extends CommonModule { - def ivyDeps = Agg(Deps.zio, Deps.tapirZIOHttp4sServer) - def moduleDeps = Seq(entity, command.endpoints.jvm) - } - object entity extends CommonModule { - def moduleDeps = Seq(model.jvm, codecs.jvm, ff.akkaPersistence) - } - } -} diff --git a/mongo/src/it/scala/works/iterative/mongo/MongoJsonFileRepositoryIntegrationSpec.scala b/mongo/src/it/scala/works/iterative/mongo/MongoJsonFileRepositoryIntegrationSpec.scala index eed0e73..f432251 100644 --- a/mongo/src/it/scala/works/iterative/mongo/MongoJsonFileRepositoryIntegrationSpec.scala +++ b/mongo/src/it/scala/works/iterative/mongo/MongoJsonFileRepositoryIntegrationSpec.scala @@ -27,9 +27,10 @@ result <- repo.matching(ByOsobniCislo("10123")) yield assertTrue(result.head.name == fname) ) - ).provideCustomLayer(layer.mapError(TestFailure.fail)) + ).provide(layer) @@ TestAspect.ifEnvSet("MONGO_URI") - val layer = + val layer + : TaskLayer[MongoJsonFileRepository[ExampleMetadata, ExampleCriteria]] = import org.mongodb.scala.* import org.mongodb.scala.model.Filters.* import org.bson.json.JsonObject diff --git a/mongo/src/it/scala/works/iterative/mongo/MongoJsonRepositoryIntegrationSpec.scala b/mongo/src/it/scala/works/iterative/mongo/MongoJsonRepositoryIntegrationSpec.scala index 0898f7d..7248c06 100644 --- a/mongo/src/it/scala/works/iterative/mongo/MongoJsonRepositoryIntegrationSpec.scala +++ b/mongo/src/it/scala/works/iterative/mongo/MongoJsonRepositoryIntegrationSpec.scala @@ -22,9 +22,9 @@ result <- repo.matching(ById("1")) yield assertTrue(result.head.value == "test") ) - ).provideCustomLayer(layer.mapError(TestFailure.fail)) + ).provide(layer) @@ TestAspect.ifEnvSet("MONGO_URI") - val layer = + val layer: TaskLayer[MongoJsonRepository[Example, String, ExampleCriteria]] = import org.mongodb.scala.* import org.mongodb.scala.model.Filters.* import org.bson.json.JsonObject diff --git a/.sbtopts b/.sbtopts new file mode 100644 index 0000000..6913385 --- /dev/null +++ b/.sbtopts @@ -0,0 +1 @@ +-mem 2048 -J-XX:+UseG1GC diff --git a/bom.sc b/bom.sc deleted file mode 100644 index 636a511..0000000 --- a/bom.sc +++ /dev/null @@ -1,234 +0,0 @@ -import mill._, scalalib._ - -object IWMaterials { - - object Versions { - val akka = "2.6.16" - val akkaHttp = "10.2.4" - val cats = "2.7.0" - val elastic4s = "7.12.2" - val http4s = "0.23.10" - val http4sPac4J = "4.0.0" - val laminar = "0.14.2" - val laminext = laminar - val logbackClassic = "1.2.10" - val pac4j = "5.2.0" - val play = "2.8.8" - val playJson = "2.9.2" - val refined = "0.9.29" - val scalaTest = "3.2.9" - val slf4j = "1.7.36" - val slick = "3.3.3" - val sttpClient = "3.5.0" - val tapir = "0.20.1" - val urlDsl = "0.4.0" - val waypoint = "0.5.0" - val zio = "2.0.0-RC2" - val zioConfig = "3.0.0-RC2" - val zioInteropCats = "3.3.0-RC2" - val zioJson = "0.3.0-RC3" - val zioLogging = "2.0.0-RC5" - val zioPrelude = "1.0.0-RC10" - val zioZMX = "0.0.11" - } - - object Deps extends AkkaLibs with SlickLibs { - import IWMaterials.{Versions => V} - - val zioOrg = "dev.zio" - - def zioLib(name: String, version: String): Dep = - ivy"$zioOrg::zio-$name::$version" - - lazy val zio: Dep = ivy"$zioOrg::zio:${V.zio}" - - lazy val zioTest: Dep = zioLib("test", V.zio) - lazy val zioTestSbt: Dep = zioLib("test-sbt", V.zio) - - lazy val zioConfig: Dep = zioLib("config", V.zioConfig) - lazy val zioConfigTypesafe: Dep = - zioLib("config-typesafe", V.zioConfig) - lazy val zioConfigMagnolia: Dep = - zioLib("config-magnolia", V.zioConfig) - - lazy val zioJson: Dep = zioLib("json", V.zioJson) - lazy val zioLogging: Dep = zioLib("logging", V.zioLogging) - lazy val zioLoggingSlf4j: Dep = - zioLib("logging-slf4j", V.zioLogging) - lazy val zioPrelude: Dep = zioLib("prelude", V.zioPrelude) - lazy val zioStreams: Dep = zioLib("streams", V.zio) - lazy val zioZMX: Dep = zioLib("zmx", V.zioZMX) - lazy val zioInteropCats: Dep = - zioLib("interop-cats", V.zioInteropCats) - - lazy val catsCore: Dep = ivy"org.typelevel::cats-core::${V.cats}" - - lazy val refined: Dep = ivy"eu.timepit::refined::${V.refined}" - - /* What is the equivalent? ZIOModule with prepared test config? - def useZIO(testConf: Configuration*): Agg[Dep] = Agg( - zio, - zioTest, - zioTestSbt, - testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework") - ) - */ - - /* - def useZIOAll(testConf: Configuration*): Seq[Def.Setting[_]] = - useZIO(testConf: _*) ++ Seq( - zioStreams, - zioConfig, - zioConfigTypesafe, - zioConfigMagnolia, - zioJson, - zioZMX, - zioLogging, - zioPrelude - ) - */ - - private val tapirOrg = "com.softwaremill.sttp.tapir" - def tapirLib(name: String): Dep = - ivy"${tapirOrg}::tapir-$name::${V.tapir}" - - lazy val tapirCore: Dep = tapirLib("core") - lazy val tapirZIO: Dep = tapirLib("zio") - lazy val tapirZIOJson: Dep = tapirLib("json-zio") - lazy val tapirSttpClient: Dep = tapirLib("sttp-client") - lazy val tapirCats: Dep = tapirLib("cats") - lazy val tapirZIOHttp4sServer: Dep = tapirLib("zio-http4s-server") - - val sttpClientOrg = "com.softwaremill.sttp.client3" - def sttpClientLib(name: String): Dep = - 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}" - - lazy val http4sPac4J: Dep = - ivy"org.pac4j::http4s-pac4j:${V.http4sPac4J}" - lazy val pac4jOIDC: Dep = - ivy"org.pac4j:pac4j-oidc:${V.pac4j}" - - lazy val scalaTest: Dep = - ivy"org.scalatest::scalatest:${V.scalaTest}" - lazy val scalaTestPlusScalacheck: Dep = - ivy"org.scalatestplus::scalacheck-1-15:3.2.9.0" - lazy val playScalaTest: Dep = - ivy"org.scalatestplus.play::scalatestplus-play:5.1.0" - - private val playOrg = "com.typesafe.play" - lazy val playMailer: Dep = ivy"${playOrg}::play-mailer:8.0.1" - lazy val playServer: Dep = ivy"${playOrg}::play-server:${V.play}" - lazy val playAkkaServer: Dep = - ivy"${playOrg}::play-akka-http-server:${V.play}" - lazy val play: Dep = ivy"${playOrg}::play:${V.play}" - lazy val playAhcWs: Dep = ivy"${playOrg}::play-ahc-ws:${V.play}" - lazy val playJson: Dep = ivy"${playOrg}::play-json:${V.playJson}" - - private val elastic4sOrg = "com.sksamuel.elastic4s" - lazy val useElastic4S: Agg[Dep] = Agg( - ivy"${elastic4sOrg}::elastic4s-core:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-client-akka:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-http-streams:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-json-play:${V.elastic4s}" - ) - - lazy val laminar: Dep = ivy"com.raquo::laminar::${V.laminar}" - - private def laminext(name: String): Dep = - ivy"io.laminext::$name::${V.laminar}" - - lazy val laminextCore: Dep = laminext("core") - lazy val laminextTailwind: Dep = laminext("tailwind") - lazy val laminextFetch: Dep = laminext("fetch") - lazy val laminextValidationCore: Dep = laminext("validation-core") - lazy val laminextUI: Dep = laminext("ui") - - lazy val waypoint: Dep = - ivy"com.raquo::waypoint::${V.waypoint}" - - lazy val urlDsl: Dep = - ivy"be.doeraene::url-dsl::${V.urlDsl}" - - lazy val scalaJavaTime: Dep = - ivy"io.github.cquiroz::scala-java-time::2.3.0" - - lazy val scalaJavaLocales: Dep = - ivy"io.github.cquiroz::scala-java-locales::1.2.1" - - lazy val logbackClassic: Dep = - ivy"ch.qos.logback:logback-classic:${V.logbackClassic}" - } - - trait AkkaLibs { - - self: SlickLibs => - - object akka { - val V = Versions.akka - val tOrg = "com.typesafe.akka" - val lOrg = "com.lightbend.akka" - - def akkaMod(name: String): Dep = - ivy"$tOrg::akka-$name:$V" - - lazy val actor: Dep = akkaMod("actor") - lazy val actorTyped: Dep = akkaMod("actor-typed") - lazy val stream: Dep = akkaMod("stream") - lazy val persistence: Dep = akkaMod("persistence-typed") - lazy val persistenceQuery: Dep = akkaMod("persistence-query") - lazy val persistenceJdbc: Dep = - ivy"$lOrg::akka-persistence-jdbc:5.0.4" - val persistenceTestKit: Dep = ivy"$tOrg::akka-persistence-testkit:$V" - - object http { - val V = Versions.akkaHttp - - lazy val http: Dep = ivy"$tOrg::akka-http:$V" - lazy val sprayJson: Dep = ivy"$tOrg::akka-http-spray-json:$V" - - } - - object projection { - val V = "1.2.2" - - lazy val core: Dep = - ivy"$lOrg::akka-projection-core:$V" - lazy val eventsourced: Dep = - ivy"$lOrg::akka-projection-eventsourced:$V" - lazy val slick: Dep = - ivy"$lOrg::akka-projection-slick:$V" - lazy val jdbc: Dep = - ivy"$lOrg::akka-projection-jdbc:$V" - } - - object profiles { - // TODO: deal with cross-version for Scala3 (for3Use2_13) - lazy val eventsourcedJdbcProjection: Agg[Dep] = Agg( - persistenceQuery, - projection.core, - projection.eventsourced, - projection.slick, - persistenceJdbc - ) ++ slick.default - } - } - } - - trait SlickLibs { - object slick { - val V = IWMaterials.Versions.slick - val org = "com.typesafe.slick" - - lazy val slick: Dep = ivy"$org::slick:$V" - lazy val hikaricp: Dep = ivy"$org::slick-hikaricp:$V" - lazy val default: Agg[Dep] = Agg(slick, hikaricp) - } - } - -} diff --git a/build.sbt b/build.sbt new file mode 100644 index 0000000..a8bc367 --- /dev/null +++ b/build.sbt @@ -0,0 +1,123 @@ +ThisBuild / scalaVersion := scala3Version + +publishToIW + +lazy val core = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .settings(name := "iw-support-core") + .in(file("core")) + .settings(IWDeps.zioPrelude) + +lazy val `tapir-support` = crossProject(JSPlatform, JVMPlatform) + .in(file("tapir")) + .settings(name := "iw-support-tapir") + .settings( + IWDeps.tapirCore, + IWDeps.tapirZIOJson, + IWDeps.useZIOJson, + IWDeps.tapirSttpClient + ) + .jvmSettings( + IWDeps.tapirZIO, + IWDeps.tapirZIOHttp4sServer, + IWDeps.useZIOJson, + IWDeps.sttpClientLib("async-http-client-backend-zio"), + IWDeps.zioLib("interop-reactivestreams", "2.0.0"), + IWDeps.zioLib("nio", "2.0.0"), + excludeDependencies += // Gets transitively dragged in by zio-nio, conflicting with _3 + ExclusionRule("org.scala-lang.modules", "scala-collection-compat_2.13") + ) + +lazy val codecs = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .in(file("codecs")) + .settings(name := "iw-support-codecs") + .settings( + IWDeps.useZIOJson, + excludeDependencies += // Gets transitively dragged in by zio-nio, conflicting with _3 + ExclusionRule("org.scala-lang.modules", "scala-collection-compat_2.13") + ) + .dependsOn(core, `tapir-support`) + +lazy val `mongo-support` = project + .in(file("mongo")) + .configs(IntegrationTest) + .settings(name := "iw-support-mongo") + .settings( + Defaults.itSettings, + IWDeps.useZIO(Test, IntegrationTest), + IWDeps.useZIOJson, + IWDeps.zioConfig, + libraryDependencies += ("org.mongodb.scala" %% "mongo-scala-driver" % "4.2.3") + .cross(CrossVersion.for3Use2_13) + ) + +lazy val `akka-persistence-support` = project + .in(file("akka-persistence")) + .settings(name := "iw-support-akka-persistence") + .settings( + IWDeps.useZIO(Test), + IWDeps.useZIOJson, + IWDeps.zioConfig, + libraryDependencies += IWDeps.akka.modules.persistence + .cross(CrossVersion.for3Use2_13), + libraryDependencies += "com.typesafe.akka" %% "akka-cluster-sharding-typed" % IWDeps.akka.V cross (CrossVersion.for3Use2_13), + IWDeps.akka.profiles.eventsourcedJdbcProjection + ) + +lazy val ui = (project in file("ui")) + .enablePlugins(ScalaJSPlugin) + .settings(name := "iw-support-ui") + .settings( + IWDeps.useZIO(Test), + IWDeps.laminar, + IWDeps.useZIOJson, + IWDeps.waypoint, + IWDeps.urlDsl, + IWDeps.laminextCore, + IWDeps.laminextUI, + IWDeps.laminextTailwind, + IWDeps.laminextValidationCore + ) + +lazy val `ui-model` = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .in(file("ui/model")) + .settings(name := "iw-support-ui-model") + .dependsOn(core) + +lazy val `ui-components` = (project in file("ui/components")) + .enablePlugins(ScalaJSPlugin) + .settings(name := "iw-support-ui-components") + .settings( + IWDeps.useZIO(Test), + IWDeps.zioPrelude, + IWDeps.laminar, + IWDeps.useZIOJson, + IWDeps.waypoint, + IWDeps.urlDsl, + IWDeps.laminextCore, + IWDeps.laminextUI, + IWDeps.laminextTailwind, + IWDeps.laminextValidationCore + ) + .dependsOn(`ui-model`.js) + +lazy val root = (project in file(".")) + .settings(name := "iw-support", publish / skip := true) + // Auto activates for all projects, but make sure we have required dependencies + .enablePlugins(IWScalaProjectPlugin, GitVersioning) + .aggregate( + core.js, + core.jvm, + codecs.js, + codecs.jvm, + `tapir-support`.js, + `tapir-support`.jvm, + `mongo-support`, + `akka-persistence-support`, + ui, + `ui-model`.js, + `ui-model`.jvm, + `ui-components` + ) diff --git a/build.sc b/build.sc deleted file mode 100644 index 3f3da4f..0000000 --- a/build.sc +++ /dev/null @@ -1,146 +0,0 @@ -import mill._, scalalib._, scalajslib._ - -import $file.bom - -object support { - val Deps = bom.IWMaterials.Deps - val Versions = bom.IWMaterials.Versions - - trait CommonModule extends ScalaModule { - def scalaVersion = "3.1.1" - def scalacOptions = T { - super.scalacOptions() ++ Seq( - "-encoding", - "utf8", - "-deprecation", - "-explain-types", - "-explain", - "-feature", - "-language:experimental.macros", - "-language:higherKinds", - "-language:implicitConversions", - "-unchecked", - "-Xfatal-warnings", - "-Ykind-projector" - ) - } - } - - trait CommonJSModule extends CommonModule with ScalaJSModule { - def scalaJSVersion = "1.9.0" - } - - trait CrossPlatformModule extends Module { outer => - def ivyDeps: T[Agg[Dep]] = Agg[Dep]() - def jsDeps: T[Agg[Dep]] = Agg[Dep]() - def jvmDeps: T[Agg[Dep]] = Agg[Dep]() - def moduleDeps: Seq[Module] = Seq[Module]() - - trait PlatformModule extends CommonModule { - def platform: String - override def millSourcePath = outer.millSourcePath - override def ivyDeps = outer.ivyDeps() ++ (platform match { - case "js" => jsDeps() - case _ => jvmDeps() - }) - override def moduleDeps = outer.moduleDeps.collect { - case m: CrossPlatformModule => - platform match { - case "js" => m.js - case _ => m.jvm - } - case m: JavaModule => m - } - } - - trait JsModule extends PlatformModule with CommonJSModule { - def platform = "js" - } - - trait JvmModule extends PlatformModule { - def platform = "jvm" - } - - val js: JsModule - val jvm: JvmModule - } - - trait PureCrossModule extends CrossPlatformModule { - override object js extends JsModule - override object jvm extends JvmModule - } - - trait PureCrossSbtModule extends CrossPlatformModule { - override object js extends JsModule with SbtModule - override object jvm extends JvmModule with SbtModule - } - - trait FullCrossSbtModule extends CrossPlatformModule { - trait FullSources extends JavaModule { self: PlatformModule => - override def sources = T.sources( - millSourcePath / platform / "src" / "main" / "scala", - millSourcePath / "shared" / "src" / "main" / "scala" - ) - - override def resources = T.sources( - millSourcePath / platform / "src" / "main" / "resources", - millSourcePath / "shared" / "src" / "main" / "resources" - ) - } - - override object js extends JsModule with FullSources - override object jvm extends JvmModule with FullSources - } - -} - -import support._ - -object mongo extends CommonModule { - def ivyDeps = Agg( - Deps.zio, - Deps.zioJson, - Deps.zioConfig, - ivy"org.mongodb.scala::mongo-scala-driver:4.2.3".withDottyCompat( - scalaVersion() - ) - ) -} - -object tapir extends FullCrossSbtModule { - def ivyDeps = Agg(Deps.tapirCore, Deps.tapirZIOJson, Deps.zioJson) - def jvmDeps = Agg(Deps.tapirZIO, Deps.tapirZIOHttp4sServer) - def jsDeps = Agg(Deps.tapirSttpClient) -} - -object akkaPersistence extends CommonModule { - def millSourcePath = build.millSourcePath / "akka-persistence" - def ivyDeps = (Agg( - Deps.akka.persistenceQuery, - Deps.akka.persistenceJdbc, - Deps.akka.projection.core, - Deps.akka.projection.eventsourced, - Deps.akka.projection.slick - ) ++ Deps.slick.default).map(_.withDottyCompat(scalaVersion())) ++ Agg( - Deps.zio, - Deps.zioJson, - Deps.zioConfig, - Deps.akka.persistence.withDottyCompat(scalaVersion()), - ivy"com.typesafe.akka::akka-cluster-sharding-typed:${Deps.akka.V}" - .withDottyCompat(scalaVersion()) - ) -} - -object ui extends CommonJSModule { - def ivyDeps = Agg( - Deps.zio, - Deps.laminar, - Deps.zioJson, - Deps.waypoint, - Deps.urlDsl, - Deps.laminextCore, - Deps.laminextUI, - Deps.laminextTailwind, - Deps.laminextValidationCore - ) -} diff --git a/domain.sc b/domain.sc deleted file mode 100644 index b09c56b..0000000 --- a/domain.sc +++ /dev/null @@ -1,78 +0,0 @@ -import mill._, scalalib._ - -import $file.{build => ff}, ff.support._ - -trait DomainModule extends Module { - // General extra model deps - def modelModules: Seq[Module] = Seq.empty - // General extra codecs deps - def codecsModules: Seq[Module] = Seq.empty - // General extra endpoints deps - def endpointsModules: Seq[Module] = Seq.empty - - // Implementation deps for repo - def repoModules: Seq[JavaModule] = Seq.empty - - object shared extends Module { - object model extends PureCrossModule { - def moduleDeps = modelModules - def ivyDeps = Agg(Deps.zioPrelude) - } - object codecs extends PureCrossModule { - def moduleDeps = Seq(model) ++ codecsModules - def ivyDeps = Agg(Deps.zioJson) - } - } - - trait CommonProjects extends Module { - object model extends PureCrossModule { - def ivyDeps = Agg(Deps.zioPrelude) - def moduleDeps = Seq(shared.model) - } - object codecs extends PureCrossModule { - def moduleDeps = - Seq(model, shared.model, shared.codecs, ff.tapir) - } - object endpoints extends PureCrossModule { - def ivyDeps = Agg(Deps.tapirCore, Deps.tapirZIOJson) - def moduleDeps = Seq(model, codecs) ++ endpointsModules - } - object client extends CommonJSModule { - def moduleDeps = Seq(endpoints.js) - } - object components extends CommonJSModule { - def ivyDeps = Agg( - Deps.laminar, - Deps.laminextCore, - Deps.laminextUI, - Deps.laminextTailwind, - Deps.laminextValidationCore - ) - def moduleDeps = Seq(model.js, codecs.js, client, ff.ui) - } - } - - object query extends CommonProjects { - object api extends CommonModule { - def ivyDeps = Agg(Deps.zio, Deps.tapirZIOHttp4sServer) - def moduleDeps = Seq(repo, query.endpoints.jvm) - } - object repo extends CommonModule { - def ivyDeps = Agg(Deps.zio) - def moduleDeps = Seq(model.jvm, codecs.jvm) ++ repoModules - } - object projection extends CommonModule { - def moduleDeps = Seq(repo, ff.akkaPersistence) - } - } - - object command extends CommonProjects { - object api extends CommonModule { - def ivyDeps = Agg(Deps.zio, Deps.tapirZIOHttp4sServer) - def moduleDeps = Seq(entity, command.endpoints.jvm) - } - object entity extends CommonModule { - def moduleDeps = Seq(model.jvm, codecs.jvm, ff.akkaPersistence) - } - } -} diff --git a/mongo/src/it/scala/works/iterative/mongo/MongoJsonFileRepositoryIntegrationSpec.scala b/mongo/src/it/scala/works/iterative/mongo/MongoJsonFileRepositoryIntegrationSpec.scala index eed0e73..f432251 100644 --- a/mongo/src/it/scala/works/iterative/mongo/MongoJsonFileRepositoryIntegrationSpec.scala +++ b/mongo/src/it/scala/works/iterative/mongo/MongoJsonFileRepositoryIntegrationSpec.scala @@ -27,9 +27,10 @@ result <- repo.matching(ByOsobniCislo("10123")) yield assertTrue(result.head.name == fname) ) - ).provideCustomLayer(layer.mapError(TestFailure.fail)) + ).provide(layer) @@ TestAspect.ifEnvSet("MONGO_URI") - val layer = + val layer + : TaskLayer[MongoJsonFileRepository[ExampleMetadata, ExampleCriteria]] = import org.mongodb.scala.* import org.mongodb.scala.model.Filters.* import org.bson.json.JsonObject diff --git a/mongo/src/it/scala/works/iterative/mongo/MongoJsonRepositoryIntegrationSpec.scala b/mongo/src/it/scala/works/iterative/mongo/MongoJsonRepositoryIntegrationSpec.scala index 0898f7d..7248c06 100644 --- a/mongo/src/it/scala/works/iterative/mongo/MongoJsonRepositoryIntegrationSpec.scala +++ b/mongo/src/it/scala/works/iterative/mongo/MongoJsonRepositoryIntegrationSpec.scala @@ -22,9 +22,9 @@ result <- repo.matching(ById("1")) yield assertTrue(result.head.value == "test") ) - ).provideCustomLayer(layer.mapError(TestFailure.fail)) + ).provide(layer) @@ TestAspect.ifEnvSet("MONGO_URI") - val layer = + val layer: TaskLayer[MongoJsonRepository[Example, String, ExampleCriteria]] = import org.mongodb.scala.* import org.mongodb.scala.model.Filters.* import org.bson.json.JsonObject diff --git a/project/build.properties b/project/build.properties new file mode 100644 index 0000000..563a014 --- /dev/null +++ b/project/build.properties @@ -0,0 +1 @@ +sbt.version=1.7.2 diff --git a/.sbtopts b/.sbtopts new file mode 100644 index 0000000..6913385 --- /dev/null +++ b/.sbtopts @@ -0,0 +1 @@ +-mem 2048 -J-XX:+UseG1GC diff --git a/bom.sc b/bom.sc deleted file mode 100644 index 636a511..0000000 --- a/bom.sc +++ /dev/null @@ -1,234 +0,0 @@ -import mill._, scalalib._ - -object IWMaterials { - - object Versions { - val akka = "2.6.16" - val akkaHttp = "10.2.4" - val cats = "2.7.0" - val elastic4s = "7.12.2" - val http4s = "0.23.10" - val http4sPac4J = "4.0.0" - val laminar = "0.14.2" - val laminext = laminar - val logbackClassic = "1.2.10" - val pac4j = "5.2.0" - val play = "2.8.8" - val playJson = "2.9.2" - val refined = "0.9.29" - val scalaTest = "3.2.9" - val slf4j = "1.7.36" - val slick = "3.3.3" - val sttpClient = "3.5.0" - val tapir = "0.20.1" - val urlDsl = "0.4.0" - val waypoint = "0.5.0" - val zio = "2.0.0-RC2" - val zioConfig = "3.0.0-RC2" - val zioInteropCats = "3.3.0-RC2" - val zioJson = "0.3.0-RC3" - val zioLogging = "2.0.0-RC5" - val zioPrelude = "1.0.0-RC10" - val zioZMX = "0.0.11" - } - - object Deps extends AkkaLibs with SlickLibs { - import IWMaterials.{Versions => V} - - val zioOrg = "dev.zio" - - def zioLib(name: String, version: String): Dep = - ivy"$zioOrg::zio-$name::$version" - - lazy val zio: Dep = ivy"$zioOrg::zio:${V.zio}" - - lazy val zioTest: Dep = zioLib("test", V.zio) - lazy val zioTestSbt: Dep = zioLib("test-sbt", V.zio) - - lazy val zioConfig: Dep = zioLib("config", V.zioConfig) - lazy val zioConfigTypesafe: Dep = - zioLib("config-typesafe", V.zioConfig) - lazy val zioConfigMagnolia: Dep = - zioLib("config-magnolia", V.zioConfig) - - lazy val zioJson: Dep = zioLib("json", V.zioJson) - lazy val zioLogging: Dep = zioLib("logging", V.zioLogging) - lazy val zioLoggingSlf4j: Dep = - zioLib("logging-slf4j", V.zioLogging) - lazy val zioPrelude: Dep = zioLib("prelude", V.zioPrelude) - lazy val zioStreams: Dep = zioLib("streams", V.zio) - lazy val zioZMX: Dep = zioLib("zmx", V.zioZMX) - lazy val zioInteropCats: Dep = - zioLib("interop-cats", V.zioInteropCats) - - lazy val catsCore: Dep = ivy"org.typelevel::cats-core::${V.cats}" - - lazy val refined: Dep = ivy"eu.timepit::refined::${V.refined}" - - /* What is the equivalent? ZIOModule with prepared test config? - def useZIO(testConf: Configuration*): Agg[Dep] = Agg( - zio, - zioTest, - zioTestSbt, - testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework") - ) - */ - - /* - def useZIOAll(testConf: Configuration*): Seq[Def.Setting[_]] = - useZIO(testConf: _*) ++ Seq( - zioStreams, - zioConfig, - zioConfigTypesafe, - zioConfigMagnolia, - zioJson, - zioZMX, - zioLogging, - zioPrelude - ) - */ - - private val tapirOrg = "com.softwaremill.sttp.tapir" - def tapirLib(name: String): Dep = - ivy"${tapirOrg}::tapir-$name::${V.tapir}" - - lazy val tapirCore: Dep = tapirLib("core") - lazy val tapirZIO: Dep = tapirLib("zio") - lazy val tapirZIOJson: Dep = tapirLib("json-zio") - lazy val tapirSttpClient: Dep = tapirLib("sttp-client") - lazy val tapirCats: Dep = tapirLib("cats") - lazy val tapirZIOHttp4sServer: Dep = tapirLib("zio-http4s-server") - - val sttpClientOrg = "com.softwaremill.sttp.client3" - def sttpClientLib(name: String): Dep = - 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}" - - lazy val http4sPac4J: Dep = - ivy"org.pac4j::http4s-pac4j:${V.http4sPac4J}" - lazy val pac4jOIDC: Dep = - ivy"org.pac4j:pac4j-oidc:${V.pac4j}" - - lazy val scalaTest: Dep = - ivy"org.scalatest::scalatest:${V.scalaTest}" - lazy val scalaTestPlusScalacheck: Dep = - ivy"org.scalatestplus::scalacheck-1-15:3.2.9.0" - lazy val playScalaTest: Dep = - ivy"org.scalatestplus.play::scalatestplus-play:5.1.0" - - private val playOrg = "com.typesafe.play" - lazy val playMailer: Dep = ivy"${playOrg}::play-mailer:8.0.1" - lazy val playServer: Dep = ivy"${playOrg}::play-server:${V.play}" - lazy val playAkkaServer: Dep = - ivy"${playOrg}::play-akka-http-server:${V.play}" - lazy val play: Dep = ivy"${playOrg}::play:${V.play}" - lazy val playAhcWs: Dep = ivy"${playOrg}::play-ahc-ws:${V.play}" - lazy val playJson: Dep = ivy"${playOrg}::play-json:${V.playJson}" - - private val elastic4sOrg = "com.sksamuel.elastic4s" - lazy val useElastic4S: Agg[Dep] = Agg( - ivy"${elastic4sOrg}::elastic4s-core:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-client-akka:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-http-streams:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-json-play:${V.elastic4s}" - ) - - lazy val laminar: Dep = ivy"com.raquo::laminar::${V.laminar}" - - private def laminext(name: String): Dep = - ivy"io.laminext::$name::${V.laminar}" - - lazy val laminextCore: Dep = laminext("core") - lazy val laminextTailwind: Dep = laminext("tailwind") - lazy val laminextFetch: Dep = laminext("fetch") - lazy val laminextValidationCore: Dep = laminext("validation-core") - lazy val laminextUI: Dep = laminext("ui") - - lazy val waypoint: Dep = - ivy"com.raquo::waypoint::${V.waypoint}" - - lazy val urlDsl: Dep = - ivy"be.doeraene::url-dsl::${V.urlDsl}" - - lazy val scalaJavaTime: Dep = - ivy"io.github.cquiroz::scala-java-time::2.3.0" - - lazy val scalaJavaLocales: Dep = - ivy"io.github.cquiroz::scala-java-locales::1.2.1" - - lazy val logbackClassic: Dep = - ivy"ch.qos.logback:logback-classic:${V.logbackClassic}" - } - - trait AkkaLibs { - - self: SlickLibs => - - object akka { - val V = Versions.akka - val tOrg = "com.typesafe.akka" - val lOrg = "com.lightbend.akka" - - def akkaMod(name: String): Dep = - ivy"$tOrg::akka-$name:$V" - - lazy val actor: Dep = akkaMod("actor") - lazy val actorTyped: Dep = akkaMod("actor-typed") - lazy val stream: Dep = akkaMod("stream") - lazy val persistence: Dep = akkaMod("persistence-typed") - lazy val persistenceQuery: Dep = akkaMod("persistence-query") - lazy val persistenceJdbc: Dep = - ivy"$lOrg::akka-persistence-jdbc:5.0.4" - val persistenceTestKit: Dep = ivy"$tOrg::akka-persistence-testkit:$V" - - object http { - val V = Versions.akkaHttp - - lazy val http: Dep = ivy"$tOrg::akka-http:$V" - lazy val sprayJson: Dep = ivy"$tOrg::akka-http-spray-json:$V" - - } - - object projection { - val V = "1.2.2" - - lazy val core: Dep = - ivy"$lOrg::akka-projection-core:$V" - lazy val eventsourced: Dep = - ivy"$lOrg::akka-projection-eventsourced:$V" - lazy val slick: Dep = - ivy"$lOrg::akka-projection-slick:$V" - lazy val jdbc: Dep = - ivy"$lOrg::akka-projection-jdbc:$V" - } - - object profiles { - // TODO: deal with cross-version for Scala3 (for3Use2_13) - lazy val eventsourcedJdbcProjection: Agg[Dep] = Agg( - persistenceQuery, - projection.core, - projection.eventsourced, - projection.slick, - persistenceJdbc - ) ++ slick.default - } - } - } - - trait SlickLibs { - object slick { - val V = IWMaterials.Versions.slick - val org = "com.typesafe.slick" - - lazy val slick: Dep = ivy"$org::slick:$V" - lazy val hikaricp: Dep = ivy"$org::slick-hikaricp:$V" - lazy val default: Agg[Dep] = Agg(slick, hikaricp) - } - } - -} diff --git a/build.sbt b/build.sbt new file mode 100644 index 0000000..a8bc367 --- /dev/null +++ b/build.sbt @@ -0,0 +1,123 @@ +ThisBuild / scalaVersion := scala3Version + +publishToIW + +lazy val core = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .settings(name := "iw-support-core") + .in(file("core")) + .settings(IWDeps.zioPrelude) + +lazy val `tapir-support` = crossProject(JSPlatform, JVMPlatform) + .in(file("tapir")) + .settings(name := "iw-support-tapir") + .settings( + IWDeps.tapirCore, + IWDeps.tapirZIOJson, + IWDeps.useZIOJson, + IWDeps.tapirSttpClient + ) + .jvmSettings( + IWDeps.tapirZIO, + IWDeps.tapirZIOHttp4sServer, + IWDeps.useZIOJson, + IWDeps.sttpClientLib("async-http-client-backend-zio"), + IWDeps.zioLib("interop-reactivestreams", "2.0.0"), + IWDeps.zioLib("nio", "2.0.0"), + excludeDependencies += // Gets transitively dragged in by zio-nio, conflicting with _3 + ExclusionRule("org.scala-lang.modules", "scala-collection-compat_2.13") + ) + +lazy val codecs = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .in(file("codecs")) + .settings(name := "iw-support-codecs") + .settings( + IWDeps.useZIOJson, + excludeDependencies += // Gets transitively dragged in by zio-nio, conflicting with _3 + ExclusionRule("org.scala-lang.modules", "scala-collection-compat_2.13") + ) + .dependsOn(core, `tapir-support`) + +lazy val `mongo-support` = project + .in(file("mongo")) + .configs(IntegrationTest) + .settings(name := "iw-support-mongo") + .settings( + Defaults.itSettings, + IWDeps.useZIO(Test, IntegrationTest), + IWDeps.useZIOJson, + IWDeps.zioConfig, + libraryDependencies += ("org.mongodb.scala" %% "mongo-scala-driver" % "4.2.3") + .cross(CrossVersion.for3Use2_13) + ) + +lazy val `akka-persistence-support` = project + .in(file("akka-persistence")) + .settings(name := "iw-support-akka-persistence") + .settings( + IWDeps.useZIO(Test), + IWDeps.useZIOJson, + IWDeps.zioConfig, + libraryDependencies += IWDeps.akka.modules.persistence + .cross(CrossVersion.for3Use2_13), + libraryDependencies += "com.typesafe.akka" %% "akka-cluster-sharding-typed" % IWDeps.akka.V cross (CrossVersion.for3Use2_13), + IWDeps.akka.profiles.eventsourcedJdbcProjection + ) + +lazy val ui = (project in file("ui")) + .enablePlugins(ScalaJSPlugin) + .settings(name := "iw-support-ui") + .settings( + IWDeps.useZIO(Test), + IWDeps.laminar, + IWDeps.useZIOJson, + IWDeps.waypoint, + IWDeps.urlDsl, + IWDeps.laminextCore, + IWDeps.laminextUI, + IWDeps.laminextTailwind, + IWDeps.laminextValidationCore + ) + +lazy val `ui-model` = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .in(file("ui/model")) + .settings(name := "iw-support-ui-model") + .dependsOn(core) + +lazy val `ui-components` = (project in file("ui/components")) + .enablePlugins(ScalaJSPlugin) + .settings(name := "iw-support-ui-components") + .settings( + IWDeps.useZIO(Test), + IWDeps.zioPrelude, + IWDeps.laminar, + IWDeps.useZIOJson, + IWDeps.waypoint, + IWDeps.urlDsl, + IWDeps.laminextCore, + IWDeps.laminextUI, + IWDeps.laminextTailwind, + IWDeps.laminextValidationCore + ) + .dependsOn(`ui-model`.js) + +lazy val root = (project in file(".")) + .settings(name := "iw-support", publish / skip := true) + // Auto activates for all projects, but make sure we have required dependencies + .enablePlugins(IWScalaProjectPlugin, GitVersioning) + .aggregate( + core.js, + core.jvm, + codecs.js, + codecs.jvm, + `tapir-support`.js, + `tapir-support`.jvm, + `mongo-support`, + `akka-persistence-support`, + ui, + `ui-model`.js, + `ui-model`.jvm, + `ui-components` + ) diff --git a/build.sc b/build.sc deleted file mode 100644 index 3f3da4f..0000000 --- a/build.sc +++ /dev/null @@ -1,146 +0,0 @@ -import mill._, scalalib._, scalajslib._ - -import $file.bom - -object support { - val Deps = bom.IWMaterials.Deps - val Versions = bom.IWMaterials.Versions - - trait CommonModule extends ScalaModule { - def scalaVersion = "3.1.1" - def scalacOptions = T { - super.scalacOptions() ++ Seq( - "-encoding", - "utf8", - "-deprecation", - "-explain-types", - "-explain", - "-feature", - "-language:experimental.macros", - "-language:higherKinds", - "-language:implicitConversions", - "-unchecked", - "-Xfatal-warnings", - "-Ykind-projector" - ) - } - } - - trait CommonJSModule extends CommonModule with ScalaJSModule { - def scalaJSVersion = "1.9.0" - } - - trait CrossPlatformModule extends Module { outer => - def ivyDeps: T[Agg[Dep]] = Agg[Dep]() - def jsDeps: T[Agg[Dep]] = Agg[Dep]() - def jvmDeps: T[Agg[Dep]] = Agg[Dep]() - def moduleDeps: Seq[Module] = Seq[Module]() - - trait PlatformModule extends CommonModule { - def platform: String - override def millSourcePath = outer.millSourcePath - override def ivyDeps = outer.ivyDeps() ++ (platform match { - case "js" => jsDeps() - case _ => jvmDeps() - }) - override def moduleDeps = outer.moduleDeps.collect { - case m: CrossPlatformModule => - platform match { - case "js" => m.js - case _ => m.jvm - } - case m: JavaModule => m - } - } - - trait JsModule extends PlatformModule with CommonJSModule { - def platform = "js" - } - - trait JvmModule extends PlatformModule { - def platform = "jvm" - } - - val js: JsModule - val jvm: JvmModule - } - - trait PureCrossModule extends CrossPlatformModule { - override object js extends JsModule - override object jvm extends JvmModule - } - - trait PureCrossSbtModule extends CrossPlatformModule { - override object js extends JsModule with SbtModule - override object jvm extends JvmModule with SbtModule - } - - trait FullCrossSbtModule extends CrossPlatformModule { - trait FullSources extends JavaModule { self: PlatformModule => - override def sources = T.sources( - millSourcePath / platform / "src" / "main" / "scala", - millSourcePath / "shared" / "src" / "main" / "scala" - ) - - override def resources = T.sources( - millSourcePath / platform / "src" / "main" / "resources", - millSourcePath / "shared" / "src" / "main" / "resources" - ) - } - - override object js extends JsModule with FullSources - override object jvm extends JvmModule with FullSources - } - -} - -import support._ - -object mongo extends CommonModule { - def ivyDeps = Agg( - Deps.zio, - Deps.zioJson, - Deps.zioConfig, - ivy"org.mongodb.scala::mongo-scala-driver:4.2.3".withDottyCompat( - scalaVersion() - ) - ) -} - -object tapir extends FullCrossSbtModule { - def ivyDeps = Agg(Deps.tapirCore, Deps.tapirZIOJson, Deps.zioJson) - def jvmDeps = Agg(Deps.tapirZIO, Deps.tapirZIOHttp4sServer) - def jsDeps = Agg(Deps.tapirSttpClient) -} - -object akkaPersistence extends CommonModule { - def millSourcePath = build.millSourcePath / "akka-persistence" - def ivyDeps = (Agg( - Deps.akka.persistenceQuery, - Deps.akka.persistenceJdbc, - Deps.akka.projection.core, - Deps.akka.projection.eventsourced, - Deps.akka.projection.slick - ) ++ Deps.slick.default).map(_.withDottyCompat(scalaVersion())) ++ Agg( - Deps.zio, - Deps.zioJson, - Deps.zioConfig, - Deps.akka.persistence.withDottyCompat(scalaVersion()), - ivy"com.typesafe.akka::akka-cluster-sharding-typed:${Deps.akka.V}" - .withDottyCompat(scalaVersion()) - ) -} - -object ui extends CommonJSModule { - def ivyDeps = Agg( - Deps.zio, - Deps.laminar, - Deps.zioJson, - Deps.waypoint, - Deps.urlDsl, - Deps.laminextCore, - Deps.laminextUI, - Deps.laminextTailwind, - Deps.laminextValidationCore - ) -} diff --git a/domain.sc b/domain.sc deleted file mode 100644 index b09c56b..0000000 --- a/domain.sc +++ /dev/null @@ -1,78 +0,0 @@ -import mill._, scalalib._ - -import $file.{build => ff}, ff.support._ - -trait DomainModule extends Module { - // General extra model deps - def modelModules: Seq[Module] = Seq.empty - // General extra codecs deps - def codecsModules: Seq[Module] = Seq.empty - // General extra endpoints deps - def endpointsModules: Seq[Module] = Seq.empty - - // Implementation deps for repo - def repoModules: Seq[JavaModule] = Seq.empty - - object shared extends Module { - object model extends PureCrossModule { - def moduleDeps = modelModules - def ivyDeps = Agg(Deps.zioPrelude) - } - object codecs extends PureCrossModule { - def moduleDeps = Seq(model) ++ codecsModules - def ivyDeps = Agg(Deps.zioJson) - } - } - - trait CommonProjects extends Module { - object model extends PureCrossModule { - def ivyDeps = Agg(Deps.zioPrelude) - def moduleDeps = Seq(shared.model) - } - object codecs extends PureCrossModule { - def moduleDeps = - Seq(model, shared.model, shared.codecs, ff.tapir) - } - object endpoints extends PureCrossModule { - def ivyDeps = Agg(Deps.tapirCore, Deps.tapirZIOJson) - def moduleDeps = Seq(model, codecs) ++ endpointsModules - } - object client extends CommonJSModule { - def moduleDeps = Seq(endpoints.js) - } - object components extends CommonJSModule { - def ivyDeps = Agg( - Deps.laminar, - Deps.laminextCore, - Deps.laminextUI, - Deps.laminextTailwind, - Deps.laminextValidationCore - ) - def moduleDeps = Seq(model.js, codecs.js, client, ff.ui) - } - } - - object query extends CommonProjects { - object api extends CommonModule { - def ivyDeps = Agg(Deps.zio, Deps.tapirZIOHttp4sServer) - def moduleDeps = Seq(repo, query.endpoints.jvm) - } - object repo extends CommonModule { - def ivyDeps = Agg(Deps.zio) - def moduleDeps = Seq(model.jvm, codecs.jvm) ++ repoModules - } - object projection extends CommonModule { - def moduleDeps = Seq(repo, ff.akkaPersistence) - } - } - - object command extends CommonProjects { - object api extends CommonModule { - def ivyDeps = Agg(Deps.zio, Deps.tapirZIOHttp4sServer) - def moduleDeps = Seq(entity, command.endpoints.jvm) - } - object entity extends CommonModule { - def moduleDeps = Seq(model.jvm, codecs.jvm, ff.akkaPersistence) - } - } -} diff --git a/mongo/src/it/scala/works/iterative/mongo/MongoJsonFileRepositoryIntegrationSpec.scala b/mongo/src/it/scala/works/iterative/mongo/MongoJsonFileRepositoryIntegrationSpec.scala index eed0e73..f432251 100644 --- a/mongo/src/it/scala/works/iterative/mongo/MongoJsonFileRepositoryIntegrationSpec.scala +++ b/mongo/src/it/scala/works/iterative/mongo/MongoJsonFileRepositoryIntegrationSpec.scala @@ -27,9 +27,10 @@ result <- repo.matching(ByOsobniCislo("10123")) yield assertTrue(result.head.name == fname) ) - ).provideCustomLayer(layer.mapError(TestFailure.fail)) + ).provide(layer) @@ TestAspect.ifEnvSet("MONGO_URI") - val layer = + val layer + : TaskLayer[MongoJsonFileRepository[ExampleMetadata, ExampleCriteria]] = import org.mongodb.scala.* import org.mongodb.scala.model.Filters.* import org.bson.json.JsonObject diff --git a/mongo/src/it/scala/works/iterative/mongo/MongoJsonRepositoryIntegrationSpec.scala b/mongo/src/it/scala/works/iterative/mongo/MongoJsonRepositoryIntegrationSpec.scala index 0898f7d..7248c06 100644 --- a/mongo/src/it/scala/works/iterative/mongo/MongoJsonRepositoryIntegrationSpec.scala +++ b/mongo/src/it/scala/works/iterative/mongo/MongoJsonRepositoryIntegrationSpec.scala @@ -22,9 +22,9 @@ result <- repo.matching(ById("1")) yield assertTrue(result.head.value == "test") ) - ).provideCustomLayer(layer.mapError(TestFailure.fail)) + ).provide(layer) @@ TestAspect.ifEnvSet("MONGO_URI") - val layer = + val layer: TaskLayer[MongoJsonRepository[Example, String, ExampleCriteria]] = import org.mongodb.scala.* import org.mongodb.scala.model.Filters.* import org.bson.json.JsonObject diff --git a/project/build.properties b/project/build.properties new file mode 100644 index 0000000..563a014 --- /dev/null +++ b/project/build.properties @@ -0,0 +1 @@ +sbt.version=1.7.2 diff --git a/project/plugins.sbt b/project/plugins.sbt new file mode 100644 index 0000000..370872c --- /dev/null +++ b/project/plugins.sbt @@ -0,0 +1,5 @@ +addIWProjects + +addScalaJSSupport + +addDependencyTreePlugin diff --git a/.sbtopts b/.sbtopts new file mode 100644 index 0000000..6913385 --- /dev/null +++ b/.sbtopts @@ -0,0 +1 @@ +-mem 2048 -J-XX:+UseG1GC diff --git a/bom.sc b/bom.sc deleted file mode 100644 index 636a511..0000000 --- a/bom.sc +++ /dev/null @@ -1,234 +0,0 @@ -import mill._, scalalib._ - -object IWMaterials { - - object Versions { - val akka = "2.6.16" - val akkaHttp = "10.2.4" - val cats = "2.7.0" - val elastic4s = "7.12.2" - val http4s = "0.23.10" - val http4sPac4J = "4.0.0" - val laminar = "0.14.2" - val laminext = laminar - val logbackClassic = "1.2.10" - val pac4j = "5.2.0" - val play = "2.8.8" - val playJson = "2.9.2" - val refined = "0.9.29" - val scalaTest = "3.2.9" - val slf4j = "1.7.36" - val slick = "3.3.3" - val sttpClient = "3.5.0" - val tapir = "0.20.1" - val urlDsl = "0.4.0" - val waypoint = "0.5.0" - val zio = "2.0.0-RC2" - val zioConfig = "3.0.0-RC2" - val zioInteropCats = "3.3.0-RC2" - val zioJson = "0.3.0-RC3" - val zioLogging = "2.0.0-RC5" - val zioPrelude = "1.0.0-RC10" - val zioZMX = "0.0.11" - } - - object Deps extends AkkaLibs with SlickLibs { - import IWMaterials.{Versions => V} - - val zioOrg = "dev.zio" - - def zioLib(name: String, version: String): Dep = - ivy"$zioOrg::zio-$name::$version" - - lazy val zio: Dep = ivy"$zioOrg::zio:${V.zio}" - - lazy val zioTest: Dep = zioLib("test", V.zio) - lazy val zioTestSbt: Dep = zioLib("test-sbt", V.zio) - - lazy val zioConfig: Dep = zioLib("config", V.zioConfig) - lazy val zioConfigTypesafe: Dep = - zioLib("config-typesafe", V.zioConfig) - lazy val zioConfigMagnolia: Dep = - zioLib("config-magnolia", V.zioConfig) - - lazy val zioJson: Dep = zioLib("json", V.zioJson) - lazy val zioLogging: Dep = zioLib("logging", V.zioLogging) - lazy val zioLoggingSlf4j: Dep = - zioLib("logging-slf4j", V.zioLogging) - lazy val zioPrelude: Dep = zioLib("prelude", V.zioPrelude) - lazy val zioStreams: Dep = zioLib("streams", V.zio) - lazy val zioZMX: Dep = zioLib("zmx", V.zioZMX) - lazy val zioInteropCats: Dep = - zioLib("interop-cats", V.zioInteropCats) - - lazy val catsCore: Dep = ivy"org.typelevel::cats-core::${V.cats}" - - lazy val refined: Dep = ivy"eu.timepit::refined::${V.refined}" - - /* What is the equivalent? ZIOModule with prepared test config? - def useZIO(testConf: Configuration*): Agg[Dep] = Agg( - zio, - zioTest, - zioTestSbt, - testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework") - ) - */ - - /* - def useZIOAll(testConf: Configuration*): Seq[Def.Setting[_]] = - useZIO(testConf: _*) ++ Seq( - zioStreams, - zioConfig, - zioConfigTypesafe, - zioConfigMagnolia, - zioJson, - zioZMX, - zioLogging, - zioPrelude - ) - */ - - private val tapirOrg = "com.softwaremill.sttp.tapir" - def tapirLib(name: String): Dep = - ivy"${tapirOrg}::tapir-$name::${V.tapir}" - - lazy val tapirCore: Dep = tapirLib("core") - lazy val tapirZIO: Dep = tapirLib("zio") - lazy val tapirZIOJson: Dep = tapirLib("json-zio") - lazy val tapirSttpClient: Dep = tapirLib("sttp-client") - lazy val tapirCats: Dep = tapirLib("cats") - lazy val tapirZIOHttp4sServer: Dep = tapirLib("zio-http4s-server") - - val sttpClientOrg = "com.softwaremill.sttp.client3" - def sttpClientLib(name: String): Dep = - 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}" - - lazy val http4sPac4J: Dep = - ivy"org.pac4j::http4s-pac4j:${V.http4sPac4J}" - lazy val pac4jOIDC: Dep = - ivy"org.pac4j:pac4j-oidc:${V.pac4j}" - - lazy val scalaTest: Dep = - ivy"org.scalatest::scalatest:${V.scalaTest}" - lazy val scalaTestPlusScalacheck: Dep = - ivy"org.scalatestplus::scalacheck-1-15:3.2.9.0" - lazy val playScalaTest: Dep = - ivy"org.scalatestplus.play::scalatestplus-play:5.1.0" - - private val playOrg = "com.typesafe.play" - lazy val playMailer: Dep = ivy"${playOrg}::play-mailer:8.0.1" - lazy val playServer: Dep = ivy"${playOrg}::play-server:${V.play}" - lazy val playAkkaServer: Dep = - ivy"${playOrg}::play-akka-http-server:${V.play}" - lazy val play: Dep = ivy"${playOrg}::play:${V.play}" - lazy val playAhcWs: Dep = ivy"${playOrg}::play-ahc-ws:${V.play}" - lazy val playJson: Dep = ivy"${playOrg}::play-json:${V.playJson}" - - private val elastic4sOrg = "com.sksamuel.elastic4s" - lazy val useElastic4S: Agg[Dep] = Agg( - ivy"${elastic4sOrg}::elastic4s-core:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-client-akka:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-http-streams:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-json-play:${V.elastic4s}" - ) - - lazy val laminar: Dep = ivy"com.raquo::laminar::${V.laminar}" - - private def laminext(name: String): Dep = - ivy"io.laminext::$name::${V.laminar}" - - lazy val laminextCore: Dep = laminext("core") - lazy val laminextTailwind: Dep = laminext("tailwind") - lazy val laminextFetch: Dep = laminext("fetch") - lazy val laminextValidationCore: Dep = laminext("validation-core") - lazy val laminextUI: Dep = laminext("ui") - - lazy val waypoint: Dep = - ivy"com.raquo::waypoint::${V.waypoint}" - - lazy val urlDsl: Dep = - ivy"be.doeraene::url-dsl::${V.urlDsl}" - - lazy val scalaJavaTime: Dep = - ivy"io.github.cquiroz::scala-java-time::2.3.0" - - lazy val scalaJavaLocales: Dep = - ivy"io.github.cquiroz::scala-java-locales::1.2.1" - - lazy val logbackClassic: Dep = - ivy"ch.qos.logback:logback-classic:${V.logbackClassic}" - } - - trait AkkaLibs { - - self: SlickLibs => - - object akka { - val V = Versions.akka - val tOrg = "com.typesafe.akka" - val lOrg = "com.lightbend.akka" - - def akkaMod(name: String): Dep = - ivy"$tOrg::akka-$name:$V" - - lazy val actor: Dep = akkaMod("actor") - lazy val actorTyped: Dep = akkaMod("actor-typed") - lazy val stream: Dep = akkaMod("stream") - lazy val persistence: Dep = akkaMod("persistence-typed") - lazy val persistenceQuery: Dep = akkaMod("persistence-query") - lazy val persistenceJdbc: Dep = - ivy"$lOrg::akka-persistence-jdbc:5.0.4" - val persistenceTestKit: Dep = ivy"$tOrg::akka-persistence-testkit:$V" - - object http { - val V = Versions.akkaHttp - - lazy val http: Dep = ivy"$tOrg::akka-http:$V" - lazy val sprayJson: Dep = ivy"$tOrg::akka-http-spray-json:$V" - - } - - object projection { - val V = "1.2.2" - - lazy val core: Dep = - ivy"$lOrg::akka-projection-core:$V" - lazy val eventsourced: Dep = - ivy"$lOrg::akka-projection-eventsourced:$V" - lazy val slick: Dep = - ivy"$lOrg::akka-projection-slick:$V" - lazy val jdbc: Dep = - ivy"$lOrg::akka-projection-jdbc:$V" - } - - object profiles { - // TODO: deal with cross-version for Scala3 (for3Use2_13) - lazy val eventsourcedJdbcProjection: Agg[Dep] = Agg( - persistenceQuery, - projection.core, - projection.eventsourced, - projection.slick, - persistenceJdbc - ) ++ slick.default - } - } - } - - trait SlickLibs { - object slick { - val V = IWMaterials.Versions.slick - val org = "com.typesafe.slick" - - lazy val slick: Dep = ivy"$org::slick:$V" - lazy val hikaricp: Dep = ivy"$org::slick-hikaricp:$V" - lazy val default: Agg[Dep] = Agg(slick, hikaricp) - } - } - -} diff --git a/build.sbt b/build.sbt new file mode 100644 index 0000000..a8bc367 --- /dev/null +++ b/build.sbt @@ -0,0 +1,123 @@ +ThisBuild / scalaVersion := scala3Version + +publishToIW + +lazy val core = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .settings(name := "iw-support-core") + .in(file("core")) + .settings(IWDeps.zioPrelude) + +lazy val `tapir-support` = crossProject(JSPlatform, JVMPlatform) + .in(file("tapir")) + .settings(name := "iw-support-tapir") + .settings( + IWDeps.tapirCore, + IWDeps.tapirZIOJson, + IWDeps.useZIOJson, + IWDeps.tapirSttpClient + ) + .jvmSettings( + IWDeps.tapirZIO, + IWDeps.tapirZIOHttp4sServer, + IWDeps.useZIOJson, + IWDeps.sttpClientLib("async-http-client-backend-zio"), + IWDeps.zioLib("interop-reactivestreams", "2.0.0"), + IWDeps.zioLib("nio", "2.0.0"), + excludeDependencies += // Gets transitively dragged in by zio-nio, conflicting with _3 + ExclusionRule("org.scala-lang.modules", "scala-collection-compat_2.13") + ) + +lazy val codecs = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .in(file("codecs")) + .settings(name := "iw-support-codecs") + .settings( + IWDeps.useZIOJson, + excludeDependencies += // Gets transitively dragged in by zio-nio, conflicting with _3 + ExclusionRule("org.scala-lang.modules", "scala-collection-compat_2.13") + ) + .dependsOn(core, `tapir-support`) + +lazy val `mongo-support` = project + .in(file("mongo")) + .configs(IntegrationTest) + .settings(name := "iw-support-mongo") + .settings( + Defaults.itSettings, + IWDeps.useZIO(Test, IntegrationTest), + IWDeps.useZIOJson, + IWDeps.zioConfig, + libraryDependencies += ("org.mongodb.scala" %% "mongo-scala-driver" % "4.2.3") + .cross(CrossVersion.for3Use2_13) + ) + +lazy val `akka-persistence-support` = project + .in(file("akka-persistence")) + .settings(name := "iw-support-akka-persistence") + .settings( + IWDeps.useZIO(Test), + IWDeps.useZIOJson, + IWDeps.zioConfig, + libraryDependencies += IWDeps.akka.modules.persistence + .cross(CrossVersion.for3Use2_13), + libraryDependencies += "com.typesafe.akka" %% "akka-cluster-sharding-typed" % IWDeps.akka.V cross (CrossVersion.for3Use2_13), + IWDeps.akka.profiles.eventsourcedJdbcProjection + ) + +lazy val ui = (project in file("ui")) + .enablePlugins(ScalaJSPlugin) + .settings(name := "iw-support-ui") + .settings( + IWDeps.useZIO(Test), + IWDeps.laminar, + IWDeps.useZIOJson, + IWDeps.waypoint, + IWDeps.urlDsl, + IWDeps.laminextCore, + IWDeps.laminextUI, + IWDeps.laminextTailwind, + IWDeps.laminextValidationCore + ) + +lazy val `ui-model` = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .in(file("ui/model")) + .settings(name := "iw-support-ui-model") + .dependsOn(core) + +lazy val `ui-components` = (project in file("ui/components")) + .enablePlugins(ScalaJSPlugin) + .settings(name := "iw-support-ui-components") + .settings( + IWDeps.useZIO(Test), + IWDeps.zioPrelude, + IWDeps.laminar, + IWDeps.useZIOJson, + IWDeps.waypoint, + IWDeps.urlDsl, + IWDeps.laminextCore, + IWDeps.laminextUI, + IWDeps.laminextTailwind, + IWDeps.laminextValidationCore + ) + .dependsOn(`ui-model`.js) + +lazy val root = (project in file(".")) + .settings(name := "iw-support", publish / skip := true) + // Auto activates for all projects, but make sure we have required dependencies + .enablePlugins(IWScalaProjectPlugin, GitVersioning) + .aggregate( + core.js, + core.jvm, + codecs.js, + codecs.jvm, + `tapir-support`.js, + `tapir-support`.jvm, + `mongo-support`, + `akka-persistence-support`, + ui, + `ui-model`.js, + `ui-model`.jvm, + `ui-components` + ) diff --git a/build.sc b/build.sc deleted file mode 100644 index 3f3da4f..0000000 --- a/build.sc +++ /dev/null @@ -1,146 +0,0 @@ -import mill._, scalalib._, scalajslib._ - -import $file.bom - -object support { - val Deps = bom.IWMaterials.Deps - val Versions = bom.IWMaterials.Versions - - trait CommonModule extends ScalaModule { - def scalaVersion = "3.1.1" - def scalacOptions = T { - super.scalacOptions() ++ Seq( - "-encoding", - "utf8", - "-deprecation", - "-explain-types", - "-explain", - "-feature", - "-language:experimental.macros", - "-language:higherKinds", - "-language:implicitConversions", - "-unchecked", - "-Xfatal-warnings", - "-Ykind-projector" - ) - } - } - - trait CommonJSModule extends CommonModule with ScalaJSModule { - def scalaJSVersion = "1.9.0" - } - - trait CrossPlatformModule extends Module { outer => - def ivyDeps: T[Agg[Dep]] = Agg[Dep]() - def jsDeps: T[Agg[Dep]] = Agg[Dep]() - def jvmDeps: T[Agg[Dep]] = Agg[Dep]() - def moduleDeps: Seq[Module] = Seq[Module]() - - trait PlatformModule extends CommonModule { - def platform: String - override def millSourcePath = outer.millSourcePath - override def ivyDeps = outer.ivyDeps() ++ (platform match { - case "js" => jsDeps() - case _ => jvmDeps() - }) - override def moduleDeps = outer.moduleDeps.collect { - case m: CrossPlatformModule => - platform match { - case "js" => m.js - case _ => m.jvm - } - case m: JavaModule => m - } - } - - trait JsModule extends PlatformModule with CommonJSModule { - def platform = "js" - } - - trait JvmModule extends PlatformModule { - def platform = "jvm" - } - - val js: JsModule - val jvm: JvmModule - } - - trait PureCrossModule extends CrossPlatformModule { - override object js extends JsModule - override object jvm extends JvmModule - } - - trait PureCrossSbtModule extends CrossPlatformModule { - override object js extends JsModule with SbtModule - override object jvm extends JvmModule with SbtModule - } - - trait FullCrossSbtModule extends CrossPlatformModule { - trait FullSources extends JavaModule { self: PlatformModule => - override def sources = T.sources( - millSourcePath / platform / "src" / "main" / "scala", - millSourcePath / "shared" / "src" / "main" / "scala" - ) - - override def resources = T.sources( - millSourcePath / platform / "src" / "main" / "resources", - millSourcePath / "shared" / "src" / "main" / "resources" - ) - } - - override object js extends JsModule with FullSources - override object jvm extends JvmModule with FullSources - } - -} - -import support._ - -object mongo extends CommonModule { - def ivyDeps = Agg( - Deps.zio, - Deps.zioJson, - Deps.zioConfig, - ivy"org.mongodb.scala::mongo-scala-driver:4.2.3".withDottyCompat( - scalaVersion() - ) - ) -} - -object tapir extends FullCrossSbtModule { - def ivyDeps = Agg(Deps.tapirCore, Deps.tapirZIOJson, Deps.zioJson) - def jvmDeps = Agg(Deps.tapirZIO, Deps.tapirZIOHttp4sServer) - def jsDeps = Agg(Deps.tapirSttpClient) -} - -object akkaPersistence extends CommonModule { - def millSourcePath = build.millSourcePath / "akka-persistence" - def ivyDeps = (Agg( - Deps.akka.persistenceQuery, - Deps.akka.persistenceJdbc, - Deps.akka.projection.core, - Deps.akka.projection.eventsourced, - Deps.akka.projection.slick - ) ++ Deps.slick.default).map(_.withDottyCompat(scalaVersion())) ++ Agg( - Deps.zio, - Deps.zioJson, - Deps.zioConfig, - Deps.akka.persistence.withDottyCompat(scalaVersion()), - ivy"com.typesafe.akka::akka-cluster-sharding-typed:${Deps.akka.V}" - .withDottyCompat(scalaVersion()) - ) -} - -object ui extends CommonJSModule { - def ivyDeps = Agg( - Deps.zio, - Deps.laminar, - Deps.zioJson, - Deps.waypoint, - Deps.urlDsl, - Deps.laminextCore, - Deps.laminextUI, - Deps.laminextTailwind, - Deps.laminextValidationCore - ) -} diff --git a/domain.sc b/domain.sc deleted file mode 100644 index b09c56b..0000000 --- a/domain.sc +++ /dev/null @@ -1,78 +0,0 @@ -import mill._, scalalib._ - -import $file.{build => ff}, ff.support._ - -trait DomainModule extends Module { - // General extra model deps - def modelModules: Seq[Module] = Seq.empty - // General extra codecs deps - def codecsModules: Seq[Module] = Seq.empty - // General extra endpoints deps - def endpointsModules: Seq[Module] = Seq.empty - - // Implementation deps for repo - def repoModules: Seq[JavaModule] = Seq.empty - - object shared extends Module { - object model extends PureCrossModule { - def moduleDeps = modelModules - def ivyDeps = Agg(Deps.zioPrelude) - } - object codecs extends PureCrossModule { - def moduleDeps = Seq(model) ++ codecsModules - def ivyDeps = Agg(Deps.zioJson) - } - } - - trait CommonProjects extends Module { - object model extends PureCrossModule { - def ivyDeps = Agg(Deps.zioPrelude) - def moduleDeps = Seq(shared.model) - } - object codecs extends PureCrossModule { - def moduleDeps = - Seq(model, shared.model, shared.codecs, ff.tapir) - } - object endpoints extends PureCrossModule { - def ivyDeps = Agg(Deps.tapirCore, Deps.tapirZIOJson) - def moduleDeps = Seq(model, codecs) ++ endpointsModules - } - object client extends CommonJSModule { - def moduleDeps = Seq(endpoints.js) - } - object components extends CommonJSModule { - def ivyDeps = Agg( - Deps.laminar, - Deps.laminextCore, - Deps.laminextUI, - Deps.laminextTailwind, - Deps.laminextValidationCore - ) - def moduleDeps = Seq(model.js, codecs.js, client, ff.ui) - } - } - - object query extends CommonProjects { - object api extends CommonModule { - def ivyDeps = Agg(Deps.zio, Deps.tapirZIOHttp4sServer) - def moduleDeps = Seq(repo, query.endpoints.jvm) - } - object repo extends CommonModule { - def ivyDeps = Agg(Deps.zio) - def moduleDeps = Seq(model.jvm, codecs.jvm) ++ repoModules - } - object projection extends CommonModule { - def moduleDeps = Seq(repo, ff.akkaPersistence) - } - } - - object command extends CommonProjects { - object api extends CommonModule { - def ivyDeps = Agg(Deps.zio, Deps.tapirZIOHttp4sServer) - def moduleDeps = Seq(entity, command.endpoints.jvm) - } - object entity extends CommonModule { - def moduleDeps = Seq(model.jvm, codecs.jvm, ff.akkaPersistence) - } - } -} diff --git a/mongo/src/it/scala/works/iterative/mongo/MongoJsonFileRepositoryIntegrationSpec.scala b/mongo/src/it/scala/works/iterative/mongo/MongoJsonFileRepositoryIntegrationSpec.scala index eed0e73..f432251 100644 --- a/mongo/src/it/scala/works/iterative/mongo/MongoJsonFileRepositoryIntegrationSpec.scala +++ b/mongo/src/it/scala/works/iterative/mongo/MongoJsonFileRepositoryIntegrationSpec.scala @@ -27,9 +27,10 @@ result <- repo.matching(ByOsobniCislo("10123")) yield assertTrue(result.head.name == fname) ) - ).provideCustomLayer(layer.mapError(TestFailure.fail)) + ).provide(layer) @@ TestAspect.ifEnvSet("MONGO_URI") - val layer = + val layer + : TaskLayer[MongoJsonFileRepository[ExampleMetadata, ExampleCriteria]] = import org.mongodb.scala.* import org.mongodb.scala.model.Filters.* import org.bson.json.JsonObject diff --git a/mongo/src/it/scala/works/iterative/mongo/MongoJsonRepositoryIntegrationSpec.scala b/mongo/src/it/scala/works/iterative/mongo/MongoJsonRepositoryIntegrationSpec.scala index 0898f7d..7248c06 100644 --- a/mongo/src/it/scala/works/iterative/mongo/MongoJsonRepositoryIntegrationSpec.scala +++ b/mongo/src/it/scala/works/iterative/mongo/MongoJsonRepositoryIntegrationSpec.scala @@ -22,9 +22,9 @@ result <- repo.matching(ById("1")) yield assertTrue(result.head.value == "test") ) - ).provideCustomLayer(layer.mapError(TestFailure.fail)) + ).provide(layer) @@ TestAspect.ifEnvSet("MONGO_URI") - val layer = + val layer: TaskLayer[MongoJsonRepository[Example, String, ExampleCriteria]] = import org.mongodb.scala.* import org.mongodb.scala.model.Filters.* import org.bson.json.JsonObject diff --git a/project/build.properties b/project/build.properties new file mode 100644 index 0000000..563a014 --- /dev/null +++ b/project/build.properties @@ -0,0 +1 @@ +sbt.version=1.7.2 diff --git a/project/plugins.sbt b/project/plugins.sbt new file mode 100644 index 0000000..370872c --- /dev/null +++ b/project/plugins.sbt @@ -0,0 +1,5 @@ +addIWProjects + +addScalaJSSupport + +addDependencyTreePlugin diff --git a/project/project/plugins.sbt b/project/project/plugins.sbt new file mode 100644 index 0000000..14d5cd2 --- /dev/null +++ b/project/project/plugins.sbt @@ -0,0 +1,7 @@ +resolvers += "IW releases" at "https://dig.iterative.works/maven/releases" + +resolvers += "IW snapshots" at "https://dig.iterative.works/maven/snapshots" + +addSbtPlugin( + "works.iterative.sbt" % "sbt-iw-plugin-presets" % "0.3.12-SNAPSHOT" +) diff --git a/.sbtopts b/.sbtopts new file mode 100644 index 0000000..6913385 --- /dev/null +++ b/.sbtopts @@ -0,0 +1 @@ +-mem 2048 -J-XX:+UseG1GC diff --git a/bom.sc b/bom.sc deleted file mode 100644 index 636a511..0000000 --- a/bom.sc +++ /dev/null @@ -1,234 +0,0 @@ -import mill._, scalalib._ - -object IWMaterials { - - object Versions { - val akka = "2.6.16" - val akkaHttp = "10.2.4" - val cats = "2.7.0" - val elastic4s = "7.12.2" - val http4s = "0.23.10" - val http4sPac4J = "4.0.0" - val laminar = "0.14.2" - val laminext = laminar - val logbackClassic = "1.2.10" - val pac4j = "5.2.0" - val play = "2.8.8" - val playJson = "2.9.2" - val refined = "0.9.29" - val scalaTest = "3.2.9" - val slf4j = "1.7.36" - val slick = "3.3.3" - val sttpClient = "3.5.0" - val tapir = "0.20.1" - val urlDsl = "0.4.0" - val waypoint = "0.5.0" - val zio = "2.0.0-RC2" - val zioConfig = "3.0.0-RC2" - val zioInteropCats = "3.3.0-RC2" - val zioJson = "0.3.0-RC3" - val zioLogging = "2.0.0-RC5" - val zioPrelude = "1.0.0-RC10" - val zioZMX = "0.0.11" - } - - object Deps extends AkkaLibs with SlickLibs { - import IWMaterials.{Versions => V} - - val zioOrg = "dev.zio" - - def zioLib(name: String, version: String): Dep = - ivy"$zioOrg::zio-$name::$version" - - lazy val zio: Dep = ivy"$zioOrg::zio:${V.zio}" - - lazy val zioTest: Dep = zioLib("test", V.zio) - lazy val zioTestSbt: Dep = zioLib("test-sbt", V.zio) - - lazy val zioConfig: Dep = zioLib("config", V.zioConfig) - lazy val zioConfigTypesafe: Dep = - zioLib("config-typesafe", V.zioConfig) - lazy val zioConfigMagnolia: Dep = - zioLib("config-magnolia", V.zioConfig) - - lazy val zioJson: Dep = zioLib("json", V.zioJson) - lazy val zioLogging: Dep = zioLib("logging", V.zioLogging) - lazy val zioLoggingSlf4j: Dep = - zioLib("logging-slf4j", V.zioLogging) - lazy val zioPrelude: Dep = zioLib("prelude", V.zioPrelude) - lazy val zioStreams: Dep = zioLib("streams", V.zio) - lazy val zioZMX: Dep = zioLib("zmx", V.zioZMX) - lazy val zioInteropCats: Dep = - zioLib("interop-cats", V.zioInteropCats) - - lazy val catsCore: Dep = ivy"org.typelevel::cats-core::${V.cats}" - - lazy val refined: Dep = ivy"eu.timepit::refined::${V.refined}" - - /* What is the equivalent? ZIOModule with prepared test config? - def useZIO(testConf: Configuration*): Agg[Dep] = Agg( - zio, - zioTest, - zioTestSbt, - testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework") - ) - */ - - /* - def useZIOAll(testConf: Configuration*): Seq[Def.Setting[_]] = - useZIO(testConf: _*) ++ Seq( - zioStreams, - zioConfig, - zioConfigTypesafe, - zioConfigMagnolia, - zioJson, - zioZMX, - zioLogging, - zioPrelude - ) - */ - - private val tapirOrg = "com.softwaremill.sttp.tapir" - def tapirLib(name: String): Dep = - ivy"${tapirOrg}::tapir-$name::${V.tapir}" - - lazy val tapirCore: Dep = tapirLib("core") - lazy val tapirZIO: Dep = tapirLib("zio") - lazy val tapirZIOJson: Dep = tapirLib("json-zio") - lazy val tapirSttpClient: Dep = tapirLib("sttp-client") - lazy val tapirCats: Dep = tapirLib("cats") - lazy val tapirZIOHttp4sServer: Dep = tapirLib("zio-http4s-server") - - val sttpClientOrg = "com.softwaremill.sttp.client3" - def sttpClientLib(name: String): Dep = - 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}" - - lazy val http4sPac4J: Dep = - ivy"org.pac4j::http4s-pac4j:${V.http4sPac4J}" - lazy val pac4jOIDC: Dep = - ivy"org.pac4j:pac4j-oidc:${V.pac4j}" - - lazy val scalaTest: Dep = - ivy"org.scalatest::scalatest:${V.scalaTest}" - lazy val scalaTestPlusScalacheck: Dep = - ivy"org.scalatestplus::scalacheck-1-15:3.2.9.0" - lazy val playScalaTest: Dep = - ivy"org.scalatestplus.play::scalatestplus-play:5.1.0" - - private val playOrg = "com.typesafe.play" - lazy val playMailer: Dep = ivy"${playOrg}::play-mailer:8.0.1" - lazy val playServer: Dep = ivy"${playOrg}::play-server:${V.play}" - lazy val playAkkaServer: Dep = - ivy"${playOrg}::play-akka-http-server:${V.play}" - lazy val play: Dep = ivy"${playOrg}::play:${V.play}" - lazy val playAhcWs: Dep = ivy"${playOrg}::play-ahc-ws:${V.play}" - lazy val playJson: Dep = ivy"${playOrg}::play-json:${V.playJson}" - - private val elastic4sOrg = "com.sksamuel.elastic4s" - lazy val useElastic4S: Agg[Dep] = Agg( - ivy"${elastic4sOrg}::elastic4s-core:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-client-akka:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-http-streams:${V.elastic4s}", - ivy"${elastic4sOrg}::elastic4s-json-play:${V.elastic4s}" - ) - - lazy val laminar: Dep = ivy"com.raquo::laminar::${V.laminar}" - - private def laminext(name: String): Dep = - ivy"io.laminext::$name::${V.laminar}" - - lazy val laminextCore: Dep = laminext("core") - lazy val laminextTailwind: Dep = laminext("tailwind") - lazy val laminextFetch: Dep = laminext("fetch") - lazy val laminextValidationCore: Dep = laminext("validation-core") - lazy val laminextUI: Dep = laminext("ui") - - lazy val waypoint: Dep = - ivy"com.raquo::waypoint::${V.waypoint}" - - lazy val urlDsl: Dep = - ivy"be.doeraene::url-dsl::${V.urlDsl}" - - lazy val scalaJavaTime: Dep = - ivy"io.github.cquiroz::scala-java-time::2.3.0" - - lazy val scalaJavaLocales: Dep = - ivy"io.github.cquiroz::scala-java-locales::1.2.1" - - lazy val logbackClassic: Dep = - ivy"ch.qos.logback:logback-classic:${V.logbackClassic}" - } - - trait AkkaLibs { - - self: SlickLibs => - - object akka { - val V = Versions.akka - val tOrg = "com.typesafe.akka" - val lOrg = "com.lightbend.akka" - - def akkaMod(name: String): Dep = - ivy"$tOrg::akka-$name:$V" - - lazy val actor: Dep = akkaMod("actor") - lazy val actorTyped: Dep = akkaMod("actor-typed") - lazy val stream: Dep = akkaMod("stream") - lazy val persistence: Dep = akkaMod("persistence-typed") - lazy val persistenceQuery: Dep = akkaMod("persistence-query") - lazy val persistenceJdbc: Dep = - ivy"$lOrg::akka-persistence-jdbc:5.0.4" - val persistenceTestKit: Dep = ivy"$tOrg::akka-persistence-testkit:$V" - - object http { - val V = Versions.akkaHttp - - lazy val http: Dep = ivy"$tOrg::akka-http:$V" - lazy val sprayJson: Dep = ivy"$tOrg::akka-http-spray-json:$V" - - } - - object projection { - val V = "1.2.2" - - lazy val core: Dep = - ivy"$lOrg::akka-projection-core:$V" - lazy val eventsourced: Dep = - ivy"$lOrg::akka-projection-eventsourced:$V" - lazy val slick: Dep = - ivy"$lOrg::akka-projection-slick:$V" - lazy val jdbc: Dep = - ivy"$lOrg::akka-projection-jdbc:$V" - } - - object profiles { - // TODO: deal with cross-version for Scala3 (for3Use2_13) - lazy val eventsourcedJdbcProjection: Agg[Dep] = Agg( - persistenceQuery, - projection.core, - projection.eventsourced, - projection.slick, - persistenceJdbc - ) ++ slick.default - } - } - } - - trait SlickLibs { - object slick { - val V = IWMaterials.Versions.slick - val org = "com.typesafe.slick" - - lazy val slick: Dep = ivy"$org::slick:$V" - lazy val hikaricp: Dep = ivy"$org::slick-hikaricp:$V" - lazy val default: Agg[Dep] = Agg(slick, hikaricp) - } - } - -} diff --git a/build.sbt b/build.sbt new file mode 100644 index 0000000..a8bc367 --- /dev/null +++ b/build.sbt @@ -0,0 +1,123 @@ +ThisBuild / scalaVersion := scala3Version + +publishToIW + +lazy val core = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .settings(name := "iw-support-core") + .in(file("core")) + .settings(IWDeps.zioPrelude) + +lazy val `tapir-support` = crossProject(JSPlatform, JVMPlatform) + .in(file("tapir")) + .settings(name := "iw-support-tapir") + .settings( + IWDeps.tapirCore, + IWDeps.tapirZIOJson, + IWDeps.useZIOJson, + IWDeps.tapirSttpClient + ) + .jvmSettings( + IWDeps.tapirZIO, + IWDeps.tapirZIOHttp4sServer, + IWDeps.useZIOJson, + IWDeps.sttpClientLib("async-http-client-backend-zio"), + IWDeps.zioLib("interop-reactivestreams", "2.0.0"), + IWDeps.zioLib("nio", "2.0.0"), + excludeDependencies += // Gets transitively dragged in by zio-nio, conflicting with _3 + ExclusionRule("org.scala-lang.modules", "scala-collection-compat_2.13") + ) + +lazy val codecs = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .in(file("codecs")) + .settings(name := "iw-support-codecs") + .settings( + IWDeps.useZIOJson, + excludeDependencies += // Gets transitively dragged in by zio-nio, conflicting with _3 + ExclusionRule("org.scala-lang.modules", "scala-collection-compat_2.13") + ) + .dependsOn(core, `tapir-support`) + +lazy val `mongo-support` = project + .in(file("mongo")) + .configs(IntegrationTest) + .settings(name := "iw-support-mongo") + .settings( + Defaults.itSettings, + IWDeps.useZIO(Test, IntegrationTest), + IWDeps.useZIOJson, + IWDeps.zioConfig, + libraryDependencies += ("org.mongodb.scala" %% "mongo-scala-driver" % "4.2.3") + .cross(CrossVersion.for3Use2_13) + ) + +lazy val `akka-persistence-support` = project + .in(file("akka-persistence")) + .settings(name := "iw-support-akka-persistence") + .settings( + IWDeps.useZIO(Test), + IWDeps.useZIOJson, + IWDeps.zioConfig, + libraryDependencies += IWDeps.akka.modules.persistence + .cross(CrossVersion.for3Use2_13), + libraryDependencies += "com.typesafe.akka" %% "akka-cluster-sharding-typed" % IWDeps.akka.V cross (CrossVersion.for3Use2_13), + IWDeps.akka.profiles.eventsourcedJdbcProjection + ) + +lazy val ui = (project in file("ui")) + .enablePlugins(ScalaJSPlugin) + .settings(name := "iw-support-ui") + .settings( + IWDeps.useZIO(Test), + IWDeps.laminar, + IWDeps.useZIOJson, + IWDeps.waypoint, + IWDeps.urlDsl, + IWDeps.laminextCore, + IWDeps.laminextUI, + IWDeps.laminextTailwind, + IWDeps.laminextValidationCore + ) + +lazy val `ui-model` = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .in(file("ui/model")) + .settings(name := "iw-support-ui-model") + .dependsOn(core) + +lazy val `ui-components` = (project in file("ui/components")) + .enablePlugins(ScalaJSPlugin) + .settings(name := "iw-support-ui-components") + .settings( + IWDeps.useZIO(Test), + IWDeps.zioPrelude, + IWDeps.laminar, + IWDeps.useZIOJson, + IWDeps.waypoint, + IWDeps.urlDsl, + IWDeps.laminextCore, + IWDeps.laminextUI, + IWDeps.laminextTailwind, + IWDeps.laminextValidationCore + ) + .dependsOn(`ui-model`.js) + +lazy val root = (project in file(".")) + .settings(name := "iw-support", publish / skip := true) + // Auto activates for all projects, but make sure we have required dependencies + .enablePlugins(IWScalaProjectPlugin, GitVersioning) + .aggregate( + core.js, + core.jvm, + codecs.js, + codecs.jvm, + `tapir-support`.js, + `tapir-support`.jvm, + `mongo-support`, + `akka-persistence-support`, + ui, + `ui-model`.js, + `ui-model`.jvm, + `ui-components` + ) diff --git a/build.sc b/build.sc deleted file mode 100644 index 3f3da4f..0000000 --- a/build.sc +++ /dev/null @@ -1,146 +0,0 @@ -import mill._, scalalib._, scalajslib._ - -import $file.bom - -object support { - val Deps = bom.IWMaterials.Deps - val Versions = bom.IWMaterials.Versions - - trait CommonModule extends ScalaModule { - def scalaVersion = "3.1.1" - def scalacOptions = T { - super.scalacOptions() ++ Seq( - "-encoding", - "utf8", - "-deprecation", - "-explain-types", - "-explain", - "-feature", - "-language:experimental.macros", - "-language:higherKinds", - "-language:implicitConversions", - "-unchecked", - "-Xfatal-warnings", - "-Ykind-projector" - ) - } - } - - trait CommonJSModule extends CommonModule with ScalaJSModule { - def scalaJSVersion = "1.9.0" - } - - trait CrossPlatformModule extends Module { outer => - def ivyDeps: T[Agg[Dep]] = Agg[Dep]() - def jsDeps: T[Agg[Dep]] = Agg[Dep]() - def jvmDeps: T[Agg[Dep]] = Agg[Dep]() - def moduleDeps: Seq[Module] = Seq[Module]() - - trait PlatformModule extends CommonModule { - def platform: String - override def millSourcePath = outer.millSourcePath - override def ivyDeps = outer.ivyDeps() ++ (platform match { - case "js" => jsDeps() - case _ => jvmDeps() - }) - override def moduleDeps = outer.moduleDeps.collect { - case m: CrossPlatformModule => - platform match { - case "js" => m.js - case _ => m.jvm - } - case m: JavaModule => m - } - } - - trait JsModule extends PlatformModule with CommonJSModule { - def platform = "js" - } - - trait JvmModule extends PlatformModule { - def platform = "jvm" - } - - val js: JsModule - val jvm: JvmModule - } - - trait PureCrossModule extends CrossPlatformModule { - override object js extends JsModule - override object jvm extends JvmModule - } - - trait PureCrossSbtModule extends CrossPlatformModule { - override object js extends JsModule with SbtModule - override object jvm extends JvmModule with SbtModule - } - - trait FullCrossSbtModule extends CrossPlatformModule { - trait FullSources extends JavaModule { self: PlatformModule => - override def sources = T.sources( - millSourcePath / platform / "src" / "main" / "scala", - millSourcePath / "shared" / "src" / "main" / "scala" - ) - - override def resources = T.sources( - millSourcePath / platform / "src" / "main" / "resources", - millSourcePath / "shared" / "src" / "main" / "resources" - ) - } - - override object js extends JsModule with FullSources - override object jvm extends JvmModule with FullSources - } - -} - -import support._ - -object mongo extends CommonModule { - def ivyDeps = Agg( - Deps.zio, - Deps.zioJson, - Deps.zioConfig, - ivy"org.mongodb.scala::mongo-scala-driver:4.2.3".withDottyCompat( - scalaVersion() - ) - ) -} - -object tapir extends FullCrossSbtModule { - def ivyDeps = Agg(Deps.tapirCore, Deps.tapirZIOJson, Deps.zioJson) - def jvmDeps = Agg(Deps.tapirZIO, Deps.tapirZIOHttp4sServer) - def jsDeps = Agg(Deps.tapirSttpClient) -} - -object akkaPersistence extends CommonModule { - def millSourcePath = build.millSourcePath / "akka-persistence" - def ivyDeps = (Agg( - Deps.akka.persistenceQuery, - Deps.akka.persistenceJdbc, - Deps.akka.projection.core, - Deps.akka.projection.eventsourced, - Deps.akka.projection.slick - ) ++ Deps.slick.default).map(_.withDottyCompat(scalaVersion())) ++ Agg( - Deps.zio, - Deps.zioJson, - Deps.zioConfig, - Deps.akka.persistence.withDottyCompat(scalaVersion()), - ivy"com.typesafe.akka::akka-cluster-sharding-typed:${Deps.akka.V}" - .withDottyCompat(scalaVersion()) - ) -} - -object ui extends CommonJSModule { - def ivyDeps = Agg( - Deps.zio, - Deps.laminar, - Deps.zioJson, - Deps.waypoint, - Deps.urlDsl, - Deps.laminextCore, - Deps.laminextUI, - Deps.laminextTailwind, - Deps.laminextValidationCore - ) -} diff --git a/domain.sc b/domain.sc deleted file mode 100644 index b09c56b..0000000 --- a/domain.sc +++ /dev/null @@ -1,78 +0,0 @@ -import mill._, scalalib._ - -import $file.{build => ff}, ff.support._ - -trait DomainModule extends Module { - // General extra model deps - def modelModules: Seq[Module] = Seq.empty - // General extra codecs deps - def codecsModules: Seq[Module] = Seq.empty - // General extra endpoints deps - def endpointsModules: Seq[Module] = Seq.empty - - // Implementation deps for repo - def repoModules: Seq[JavaModule] = Seq.empty - - object shared extends Module { - object model extends PureCrossModule { - def moduleDeps = modelModules - def ivyDeps = Agg(Deps.zioPrelude) - } - object codecs extends PureCrossModule { - def moduleDeps = Seq(model) ++ codecsModules - def ivyDeps = Agg(Deps.zioJson) - } - } - - trait CommonProjects extends Module { - object model extends PureCrossModule { - def ivyDeps = Agg(Deps.zioPrelude) - def moduleDeps = Seq(shared.model) - } - object codecs extends PureCrossModule { - def moduleDeps = - Seq(model, shared.model, shared.codecs, ff.tapir) - } - object endpoints extends PureCrossModule { - def ivyDeps = Agg(Deps.tapirCore, Deps.tapirZIOJson) - def moduleDeps = Seq(model, codecs) ++ endpointsModules - } - object client extends CommonJSModule { - def moduleDeps = Seq(endpoints.js) - } - object components extends CommonJSModule { - def ivyDeps = Agg( - Deps.laminar, - Deps.laminextCore, - Deps.laminextUI, - Deps.laminextTailwind, - Deps.laminextValidationCore - ) - def moduleDeps = Seq(model.js, codecs.js, client, ff.ui) - } - } - - object query extends CommonProjects { - object api extends CommonModule { - def ivyDeps = Agg(Deps.zio, Deps.tapirZIOHttp4sServer) - def moduleDeps = Seq(repo, query.endpoints.jvm) - } - object repo extends CommonModule { - def ivyDeps = Agg(Deps.zio) - def moduleDeps = Seq(model.jvm, codecs.jvm) ++ repoModules - } - object projection extends CommonModule { - def moduleDeps = Seq(repo, ff.akkaPersistence) - } - } - - object command extends CommonProjects { - object api extends CommonModule { - def ivyDeps = Agg(Deps.zio, Deps.tapirZIOHttp4sServer) - def moduleDeps = Seq(entity, command.endpoints.jvm) - } - object entity extends CommonModule { - def moduleDeps = Seq(model.jvm, codecs.jvm, ff.akkaPersistence) - } - } -} diff --git a/mongo/src/it/scala/works/iterative/mongo/MongoJsonFileRepositoryIntegrationSpec.scala b/mongo/src/it/scala/works/iterative/mongo/MongoJsonFileRepositoryIntegrationSpec.scala index eed0e73..f432251 100644 --- a/mongo/src/it/scala/works/iterative/mongo/MongoJsonFileRepositoryIntegrationSpec.scala +++ b/mongo/src/it/scala/works/iterative/mongo/MongoJsonFileRepositoryIntegrationSpec.scala @@ -27,9 +27,10 @@ result <- repo.matching(ByOsobniCislo("10123")) yield assertTrue(result.head.name == fname) ) - ).provideCustomLayer(layer.mapError(TestFailure.fail)) + ).provide(layer) @@ TestAspect.ifEnvSet("MONGO_URI") - val layer = + val layer + : TaskLayer[MongoJsonFileRepository[ExampleMetadata, ExampleCriteria]] = import org.mongodb.scala.* import org.mongodb.scala.model.Filters.* import org.bson.json.JsonObject diff --git a/mongo/src/it/scala/works/iterative/mongo/MongoJsonRepositoryIntegrationSpec.scala b/mongo/src/it/scala/works/iterative/mongo/MongoJsonRepositoryIntegrationSpec.scala index 0898f7d..7248c06 100644 --- a/mongo/src/it/scala/works/iterative/mongo/MongoJsonRepositoryIntegrationSpec.scala +++ b/mongo/src/it/scala/works/iterative/mongo/MongoJsonRepositoryIntegrationSpec.scala @@ -22,9 +22,9 @@ result <- repo.matching(ById("1")) yield assertTrue(result.head.value == "test") ) - ).provideCustomLayer(layer.mapError(TestFailure.fail)) + ).provide(layer) @@ TestAspect.ifEnvSet("MONGO_URI") - val layer = + val layer: TaskLayer[MongoJsonRepository[Example, String, ExampleCriteria]] = import org.mongodb.scala.* import org.mongodb.scala.model.Filters.* import org.bson.json.JsonObject diff --git a/project/build.properties b/project/build.properties new file mode 100644 index 0000000..563a014 --- /dev/null +++ b/project/build.properties @@ -0,0 +1 @@ +sbt.version=1.7.2 diff --git a/project/plugins.sbt b/project/plugins.sbt new file mode 100644 index 0000000..370872c --- /dev/null +++ b/project/plugins.sbt @@ -0,0 +1,5 @@ +addIWProjects + +addScalaJSSupport + +addDependencyTreePlugin diff --git a/project/project/plugins.sbt b/project/project/plugins.sbt new file mode 100644 index 0000000..14d5cd2 --- /dev/null +++ b/project/project/plugins.sbt @@ -0,0 +1,7 @@ +resolvers += "IW releases" at "https://dig.iterative.works/maven/releases" + +resolvers += "IW snapshots" at "https://dig.iterative.works/maven/snapshots" + +addSbtPlugin( + "works.iterative.sbt" % "sbt-iw-plugin-presets" % "0.3.12-SNAPSHOT" +) diff --git a/ui/components/src/main/scala/works/iterative/ui/components/tailwind/Display.scala b/ui/components/src/main/scala/works/iterative/ui/components/tailwind/Display.scala index f23f0e8..6cda48b 100644 --- a/ui/components/src/main/scala/works/iterative/ui/components/tailwind/Display.scala +++ b/ui/components/src/main/scala/works/iterative/ui/components/tailwind/Display.scala @@ -9,7 +9,7 @@ enum DisplayClass: case block, `inline-block`, `inline`, flex, `inline-flex`, table, - `inline-table`, `table-caption` + `inline-table`, `table-caption` object ShowUpFrom: inline def apply(