Zak Patterson
5 years ago
13 changed files with 706 additions and 0 deletions
-
142.gitignore
-
23.scalafmt.conf
-
33.travis.yml
-
8README.md
-
77build.sbt
-
43docs/Intro.md
-
220outwatch-router/src/main/scala/outwatch/router/Path.scala
-
9outwatch-router/src/main/scala/outwatch/router/State.scala
-
84project/Dependencies.scala
-
58project/Options.scala
-
4project/Version.scala
-
1project/build.properties
-
4project/plugins.sbt
@ -0,0 +1,142 @@ |
|||
|
|||
# Created by https://www.gitignore.io/api/sbt,scala,bloop,metals,intellij,sublimetext |
|||
# Edit at https://www.gitignore.io/?templates=sbt,scala,bloop,metals,intellij,sublimetext |
|||
|
|||
### Bloop ### |
|||
.bloop/ |
|||
|
|||
### Intellij ### |
|||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm |
|||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 |
|||
|
|||
# User-specific stuff |
|||
.idea/**/workspace.xml |
|||
.idea/**/tasks.xml |
|||
.idea/**/usage.statistics.xml |
|||
.idea/**/dictionaries |
|||
.idea/**/shelf |
|||
|
|||
# Generated files |
|||
.idea/**/contentModel.xml |
|||
|
|||
# Sensitive or high-churn files |
|||
.idea/**/dataSources/ |
|||
.idea/**/dataSources.ids |
|||
.idea/**/dataSources.local.xml |
|||
.idea/**/sqlDataSources.xml |
|||
.idea/**/dynamic.xml |
|||
.idea/**/uiDesigner.xml |
|||
.idea/**/dbnavigator.xml |
|||
|
|||
# Gradle |
|||
.idea/**/gradle.xml |
|||
.idea/**/libraries |
|||
|
|||
# Gradle and Maven with auto-import |
|||
# When using Gradle or Maven with auto-import, you should exclude module files, |
|||
# since they will be recreated, and may cause churn. Uncomment if using |
|||
# auto-import. |
|||
# .idea/modules.xml |
|||
# .idea/*.iml |
|||
# .idea/modules |
|||
|
|||
# CMake |
|||
cmake-build-*/ |
|||
|
|||
# Mongo Explorer plugin |
|||
.idea/**/mongoSettings.xml |
|||
|
|||
# File-based project format |
|||
*.iws |
|||
|
|||
# IntelliJ |
|||
out/ |
|||
|
|||
# mpeltonen/sbt-idea plugin |
|||
.idea_modules/ |
|||
|
|||
# JIRA plugin |
|||
atlassian-ide-plugin.xml |
|||
|
|||
# Cursive Clojure plugin |
|||
.idea/replstate.xml |
|||
|
|||
# Crashlytics plugin (for Android Studio and IntelliJ) |
|||
com_crashlytics_export_strings.xml |
|||
crashlytics.properties |
|||
crashlytics-build.properties |
|||
fabric.properties |
|||
|
|||
# Editor-based Rest Client |
|||
.idea/httpRequests |
|||
|
|||
# Android studio 3.1+ serialized cache file |
|||
.idea/caches/build_file_checksums.ser |
|||
|
|||
### Intellij Patch ### |
|||
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 |
|||
|
|||
# *.iml |
|||
# modules.xml |
|||
# .idea/misc.xml |
|||
# *.ipr |
|||
|
|||
# Sonarlint plugin |
|||
.idea/sonarlint |
|||
|
|||
### Metals ### |
|||
.metals/ |
|||
|
|||
### SBT ### |
|||
# Simple Build Tool |
|||
# http://www.scala-sbt.org/release/docs/Getting-Started/Directories.html#configuring-version-control |
|||
|
|||
dist/* |
|||
target/ |
|||
lib_managed/ |
|||
src_managed/ |
|||
project/boot/ |
|||
project/plugins/project/ |
|||
.history |
|||
.cache |
|||
.lib/ |
|||
|
|||
### Scala ### |
|||
*.class |
|||
*.log |
|||
|
|||
### SublimeText ### |
|||
# Cache files for Sublime Text |
|||
*.tmlanguage.cache |
|||
*.tmPreferences.cache |
|||
*.stTheme.cache |
|||
|
|||
# Workspace files are user-specific |
|||
*.sublime-workspace |
|||
|
|||
# Project files should be checked into the repository, unless a significant |
|||
# proportion of contributors will probably not be using Sublime Text |
|||
# *.sublime-project |
|||
|
|||
# SFTP configuration file |
|||
sftp-config.json |
|||
|
|||
# Package control specific files |
|||
Package Control.last-run |
|||
Package Control.ca-list |
|||
Package Control.ca-bundle |
|||
Package Control.system-ca-bundle |
|||
Package Control.cache/ |
|||
Package Control.ca-certs/ |
|||
Package Control.merged-ca-bundle |
|||
Package Control.user-ca-bundle |
|||
oscrypto-ca-bundle.crt |
|||
bh_unicode_properties.cache |
|||
|
|||
# Sublime-github package stores a github token in this file |
|||
# https://packagecontrol.io/packages/sublime-github |
|||
GitHub.sublime-settings |
|||
|
|||
# End of https://www.gitignore.io/api/sbt,scala,bloop,metals,intellij,sublimetext |
|||
|
|||
/.idea/ |
@ -0,0 +1,23 @@ |
|||
style = default |
|||
|
|||
maxColumn = 100 |
|||
|
|||
// Vertical alignment is pretty, but leads to bigger diffs |
|||
align = none |
|||
|
|||
// Insist on trailing commas for better difs in element construction |
|||
trailingCommas = always |
|||
danglingParentheses = true |
|||
|
|||
rewrite.rules = [ |
|||
AvoidInfix |
|||
RedundantBraces |
|||
RedundantParens |
|||
AsciiSortImports |
|||
PreferCurlyFors |
|||
] |
|||
|
|||
project.excludeFilters = [ |
|||
"scalafix-inputs", |
|||
"scalafix-outputs" |
|||
] |
@ -0,0 +1,33 @@ |
|||
language: scala |
|||
|
|||
install: |
|||
- rvm use 2.3.0 --install --fuzzy |
|||
- gem update --system |
|||
- gem install sass |
|||
- gem install jekyll -v 3.2.1 |
|||
|
|||
scala: |
|||
- 2.12.8 |
|||
|
|||
jobs: |
|||
include: |
|||
- stage: verify |
|||
|
|||
script: |
|||
- sbt ++$TRAVIS_SCALA_VERSION todomvc/fullOptJS::webpack |
|||
- sbt docs/mdoc |
|||
- sbt docs/makeMicrosite |
|||
- mkdir -p router-docs/site/todomvc |
|||
- cp -R router-docs/target/site/* ./router-docs/site/ |
|||
- cp ./router-docs/site/Readme.html ./router-docs/site/index.html |
|||
|
|||
deploy: |
|||
provider: pages |
|||
skip-cleanup: true |
|||
github-token: $GITHUB_TOKEN # Set in the settings page of your repository, as a secure variable |
|||
keep-history: true |
|||
local-dir: router-docs/site |
|||
target-branch: gh-pages |
|||
on: |
|||
branch: master |
|||
|
@ -0,0 +1,8 @@ |
|||
outwatch-router |
|||
=== |
|||
|
|||
Easy routing for [outwatch](https://outwatch.github.io) on scala.js |
|||
|
|||
Most of this code is adapted from [http4s](http4s.org)'s route parsing and path pattern matching. |
|||
|
|||
See [documentation](https://clovellytech.github.io/outwatch-router/index.html) |
@ -0,0 +1,77 @@ |
|||
import dependencies._ |
|||
|
|||
cancelable in Global := true |
|||
|
|||
val commonSettings = Seq( |
|||
organization := "com.clovellytech", |
|||
version := Version.version, |
|||
scalaVersion := Version.scalaVersion, |
|||
resolvers ++= addResolvers, |
|||
scalacOptions ++= options.scalac, |
|||
scalacOptions in (Compile, console) := options.scalacConsole, |
|||
updateOptions := updateOptions.value.withLatestSnapshots(false) |
|||
) ++ compilerPlugins |
|||
|
|||
val withTests : String = "compile->compile;test->test" |
|||
val testOnly : String = "test->test" |
|||
|
|||
lazy val docs = (project in file("./router-docs")) |
|||
.settings(name := "outwatch-router-docs") |
|||
.enablePlugins(MdocPlugin) |
|||
.settings(commonSettings) |
|||
.dependsOn(router) |
|||
|
|||
lazy val copyFastOptJS = TaskKey[Unit]("copyFastOptJS", "Copy javascript files to target directory") |
|||
|
|||
lazy val router = (project in file("./outwatch-router")) |
|||
.settings(name := "outwatch-router") |
|||
.enablePlugins(ScalaJSPlugin) |
|||
.enablePlugins(ScalaJSBundlerPlugin) |
|||
.settings(commonSettings) |
|||
.settings( |
|||
scalaJSModuleKind := ModuleKind.CommonJSModule, |
|||
scalacOptions += "-P:scalajs:sjsDefinedByDefault", |
|||
useYarn := true, // makes scalajs-bundler use yarn instead of npm |
|||
jsEnv in Test := new org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv, |
|||
scalaJSUseMainModuleInitializer := true, |
|||
scalaJSModuleKind := ModuleKind.CommonJSModule, // configure Scala.js to emit a JavaScript module instead of a top-level script |
|||
version in webpack := "4.16.1", |
|||
version in startWebpackDevServer := "3.1.4", |
|||
webpackDevServerExtraArgs := Seq("--progress", "--color"), |
|||
webpackConfigFile in fastOptJS := Some(baseDirectory.value / "webpack.config.dev.js"), |
|||
// https://scalacenter.github.io/scalajs-bundler/cookbook.html#performance |
|||
webpackBundlingMode in fastOptJS := BundlingMode.LibraryOnly(), |
|||
resolvers += "jitpack" at "https://jitpack.io", |
|||
libraryDependencies ++= Seq( |
|||
"io.github.outwatch" % "outwatch" % "ea240c6d04", |
|||
"org.http4s" %% "parboiled" % "1.0.0", |
|||
"org.scalatest" %%% "scalatest" % "3.0.5" % Test |
|||
), |
|||
copyFastOptJS := { |
|||
val inDir = (crossTarget in (Compile, fastOptJS)).value |
|||
val outDir = (crossTarget in (Compile, fastOptJS)).value / "dev" |
|||
val files = Seq("outwatch-router-fastopt-loader.js", "outwatch-router-frontend-fastopt.js", "outwatch-router-frontend-fastopt.js.map") map { p => (inDir / p, outDir / p) } |
|||
IO.copy(files, overwrite = true, preserveLastModified = true, preserveExecutable = true) |
|||
}, |
|||
// hot reloading configuration: |
|||
// https://github.com/scalacenter/scalajs-bundler/issues/180 |
|||
addCommandAlias("dev", "; compile; fastOptJS::startWebpackDevServer; devwatch; fastOptJS::stopWebpackDevServer"), |
|||
addCommandAlias("devwatch", "~; fastOptJS; copyFastOptJS") |
|||
) |
|||
|
|||
lazy val exampleApp = (project in file("router-example")) |
|||
.settings(name := "outwatch-example") |
|||
.settings(commonSettings) |
|||
.dependsOn(router) |
|||
|
|||
lazy val root = (project in file(".")) |
|||
.settings(name := "outwatch-router-root") |
|||
.settings(commonSettings) |
|||
.settings( |
|||
skip in publish := true, |
|||
aggregate in reStart := false, |
|||
) |
|||
.dependsOn(router) |
|||
.aggregate(router) |
|||
|
|||
|
@ -0,0 +1,43 @@ |
|||
Outwatch Router |
|||
=== |
|||
|
|||
```scala mdoc |
|||
import cats._ |
|||
import cats.implicits._ |
|||
import cats.Applicative |
|||
import cats.data.Kleisli |
|||
import outwatch.router._, Router._ |
|||
|
|||
sealed abstract class Page |
|||
case class RootPage() extends Page |
|||
case class Login() extends Page |
|||
case class Register() extends Page |
|||
case class Profile(userId: String) extends Page |
|||
case class NotFound() extends Page |
|||
|
|||
object Page{ |
|||
def root: Page = RootPage() |
|||
def login: Page = Login() |
|||
def register: Page = Register() |
|||
def profile(userId: String): Page = Profile(userId) |
|||
def notFound: Page = NotFound() |
|||
} |
|||
|
|||
def routes[F[_]: Applicative]: AppRouter[F, Page] = Kleisli[F, Path, Page] { |
|||
case Root => Page.root.pure[F] |
|||
case Root / "login" => Page.login.pure[F] |
|||
case Root / "register" => Page.register.pure[F] |
|||
case Root / "profile" / userId => Page.profile(userId).pure[F] |
|||
case _ => Page.notFound.pure[F] |
|||
} |
|||
|
|||
val router = routes[Id] |
|||
|
|||
router.run(Root) |
|||
router.run(Root / "login") |
|||
router.run(Root / "profile" / "saopa98f") |
|||
|
|||
router.run(Path("/profile/asd")) |
|||
router.run(Path("/apsinoasn")) |
|||
``` |
|||
|
@ -0,0 +1,220 @@ |
|||
// Completely copied from org.http4s.dsl.impl |
|||
|
|||
package outwatch.router |
|||
|
|||
import cats.implicits._ |
|||
import java.nio.{ByteBuffer, CharBuffer} |
|||
import java.nio.charset.Charset |
|||
import java.nio.charset.StandardCharsets.UTF_8 |
|||
|
|||
/** Base class for path extractors. */ |
|||
trait Path { |
|||
def /(child: String) = new /(this, child) |
|||
def toList: List[String] |
|||
def parent: Path |
|||
def lastOption: Option[String] |
|||
def startsWith(other: Path): Boolean |
|||
} |
|||
|
|||
object Path { |
|||
|
|||
/** Constructs a path from a single string by splitting on the `'/'` |
|||
* character. |
|||
* |
|||
* Leading slashes do not create an empty path segment. This is to |
|||
* reflect that there is no distinction between a request to |
|||
* `http://www.example.com` from `http://www.example.com/`. |
|||
* |
|||
* Trailing slashes result in a path with an empty final segment, |
|||
* unless the path is `"/"`, which is `Root`. |
|||
* |
|||
* Segments are URL decoded. |
|||
* |
|||
* {{{ |
|||
* scala> Path("").toList |
|||
* res0: List[String] = List() |
|||
* scala> Path("/").toList |
|||
* res1: List[String] = List() |
|||
* scala> Path("a").toList |
|||
* res2: List[String] = List(a) |
|||
* scala> Path("/a").toList |
|||
* res3: List[String] = List(a) |
|||
* scala> Path("/a/").toList |
|||
* res4: List[String] = List(a, "") |
|||
* scala> Path("//a").toList |
|||
* res5: List[String] = List("", a) |
|||
* scala> Path("/%2F").toList |
|||
* res0: List[String] = List(/) |
|||
* }}} |
|||
*/ |
|||
def apply(str: String): Path = |
|||
if (str == "" || str == "/") |
|||
Root |
|||
else { |
|||
val segments = str.split("/", -1) |
|||
// .head is safe because split always returns non-empty array |
|||
val segments0 = if (segments.head == "") segments.drop(1) else segments |
|||
segments0.foldLeft(Root: Path)((path, seg) => path / UrlCodingUtils.urlDecode(seg)) |
|||
} |
|||
|
|||
def apply(first: String, rest: String*): Path = |
|||
rest.foldLeft(Root / first)(_ / _) |
|||
|
|||
def apply(list: List[String]): Path = |
|||
list.foldLeft(Root: Path)(_ / _) |
|||
|
|||
def unapplySeq(path: Path): Some[List[String]] = |
|||
Some(path.toList) |
|||
// |
|||
// def unapplySeq[F[_]](request: Request[F]): Some[List[String]] = |
|||
// Some(Path(request.pathInfo).toList) |
|||
} |
|||
|
|||
|
|||
final case class /(parent: Path, child: String) extends Path { |
|||
lazy val toList: List[String] = parent.toList ++ List(child) |
|||
|
|||
def lastOption: Some[String] = Some(child) |
|||
|
|||
lazy val asString: String = s"$parent/${UrlCodingUtils.pathEncode(child)}" |
|||
override def toString: String = asString |
|||
def startsWith(other: Path): Boolean = { |
|||
val components = other.toList |
|||
toList.take(components.length) === components |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Root extractor: |
|||
* {{{ |
|||
* Path("/") match { |
|||
* case Root => ... |
|||
* } |
|||
* }}} |
|||
*/ |
|||
case object Root extends Path { |
|||
def toList: List[String] = Nil |
|||
def parent: Path = this |
|||
def lastOption: None.type = None |
|||
override def toString = "" |
|||
def startsWith(other: Path): Boolean = other == Root |
|||
} |
|||
|
|||
|
|||
private[router] object UrlCodingUtils { |
|||
|
|||
private val lower = ('a' to 'z').toSet |
|||
private val upper = ('A' to 'Z').toSet |
|||
private val num = ('0' to '9').toSet |
|||
val Unreserved: Set[Char] = lower ++ upper ++ num ++ "-_.~" |
|||
|
|||
private val toSkip : Set[Char] = Unreserved ++ "!$&'()*+,;=:/?@" |
|||
|
|||
private val HexUpperCaseChars: Array[Char] = ('A' to 'F').toArray |
|||
/** |
|||
* Percent-encodes a string. Depending on the parameters, this method is |
|||
* appropriate for URI or URL form encoding. Any resulting percent-encodings |
|||
* are normalized to uppercase. |
|||
* |
|||
* @param toEncode the string to encode |
|||
* @param charset the charset to use for characters that are percent encoded |
|||
* @param spaceIsPlus if space is not skipped, determines whether it will be |
|||
* rendreed as a `"+"` or a percent-encoding according to `charset`. |
|||
* @param toSkip a predicate of characters exempt from encoding. In typical |
|||
* use, this is composed of all Unreserved URI characters and sometimes a |
|||
* subset of Reserved URI characters. |
|||
*/ |
|||
def urlEncode( |
|||
toEncode: String, |
|||
charset: Charset = UTF_8, |
|||
spaceIsPlus: Boolean = false, |
|||
toSkip: Char => Boolean = toSkip): String = { |
|||
val in = charset.encode(toEncode) |
|||
val out = CharBuffer.allocate((in.remaining() * 3).toInt) |
|||
while (in.hasRemaining) { |
|||
val c = in.get().toChar |
|||
if (toSkip(c)) { |
|||
out.put(c) |
|||
} else if (c == ' ' && spaceIsPlus) { |
|||
out.put('+') |
|||
} else { |
|||
out.put('%') |
|||
out.put(HexUpperCaseChars((c >> 4) & 0xF)) |
|||
out.put(HexUpperCaseChars(c & 0xF)) |
|||
} |
|||
} |
|||
out.flip() |
|||
out.toString |
|||
} |
|||
|
|||
private val SkipEncodeInPath = |
|||
Unreserved ++ ":@!$&'()*+,;=" |
|||
|
|||
def pathEncode(s: String, charset: Charset = UTF_8): String = |
|||
UrlCodingUtils.urlEncode(s, charset, false, SkipEncodeInPath) |
|||
|
|||
/** |
|||
* Percent-decodes a string. |
|||
* |
|||
* @param toDecode the string to decode |
|||
* @param charset the charset of percent-encoded characters |
|||
* @param plusIsSpace true if `'+'` is to be interpreted as a `' '` |
|||
* @param toSkip a predicate of characters whose percent-encoded form |
|||
* is left percent-encoded. Almost certainly should be left empty. |
|||
*/ |
|||
def urlDecode( |
|||
toDecode: String, |
|||
charset: Charset = UTF_8, |
|||
plusIsSpace: Boolean = false, |
|||
toSkip: Char => Boolean = Function.const(false)): String = { |
|||
val in = CharBuffer.wrap(toDecode) |
|||
// reserve enough space for 3-byte UTF-8 characters. 4-byte characters are represented |
|||
// as surrogate pairs of characters, and will get a luxurious 6 bytes of space. |
|||
val out = ByteBuffer.allocate(in.remaining() * 3) |
|||
while (in.hasRemaining) { |
|||
val mark = in.position() |
|||
val c = in.get() |
|||
if (c == '%') { |
|||
if (in.remaining() >= 2) { |
|||
val xc = in.get() |
|||
val yc = in.get() |
|||
// scalastyle:off magic.number |
|||
val x = Character.digit(xc, 0x10) |
|||
val y = Character.digit(yc, 0x10) |
|||
// scalastyle:on magic.number |
|||
if (x != -1 && y != -1) { |
|||
val oo = (x << 4) + y |
|||
if (!toSkip(oo.toChar)) { |
|||
out.put(oo.toByte) |
|||
} else { |
|||
out.put('%'.toByte) |
|||
out.put(xc.toByte) |
|||
out.put(yc.toByte) |
|||
} |
|||
} else { |
|||
out.put('%'.toByte) |
|||
in.position(mark + 1) |
|||
} |
|||
} else { |
|||
// This is an invalid encoding. Fail gracefully by treating the '%' as |
|||
// a literal. |
|||
out.put(c.toByte) |
|||
while (in.hasRemaining) out.put(in.get().toByte) |
|||
} |
|||
} else if (c == '+' && plusIsSpace) { |
|||
out.put(' '.toByte) |
|||
} else { |
|||
// normally `out.put(c.toByte)` would be enough since the url is %-encoded, |
|||
// however there are cases where a string can be partially decoded |
|||
// so we have to make sure the non us-ascii chars get preserved properly. |
|||
if (this.toSkip(c)) { |
|||
out.put(c.toByte) |
|||
} else { |
|||
out.put(charset.encode(String.valueOf(c))) |
|||
} |
|||
} |
|||
} |
|||
out.flip() |
|||
charset.decode(out).toString |
|||
} |
|||
} |
@ -0,0 +1,9 @@ |
|||
package outwatch.router |
|||
|
|||
import cats.data.Kleisli |
|||
|
|||
object Router { |
|||
type AppRouter[F[_], A] = Kleisli[F, Path, A] |
|||
val AppRouter = Kleisli |
|||
|
|||
} |
@ -0,0 +1,84 @@ |
|||
import sbt._ |
|||
import sbt.librarymanagement.DependencyBuilders |
|||
import org.portablescala.sbtplatformdeps._ |
|||
|
|||
object dependencies { |
|||
val addResolvers = Seq( |
|||
"52north for postgis" at "http://52north.org/maven/repo/releases/", |
|||
Resolver.sonatypeRepo("releases"), |
|||
Resolver.sonatypeRepo("snapshots") |
|||
) |
|||
|
|||
val compilerPlugins = Seq( |
|||
addCompilerPlugin("org.spire-math" %% "kind-projector" % "0.9.9"), |
|||
addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.1" cross CrossVersion.full) |
|||
) |
|||
|
|||
val bcrypt = "3.1" |
|||
val cats = "1.4.0" |
|||
val catsMtl = "0.4.0" |
|||
val catsEffect = "1.2.0" |
|||
val circe = "0.11.0" |
|||
val circeConfig = "0.6.1" |
|||
val doobie = "0.6.0" |
|||
val flyway = "5.2.4" |
|||
val fs2 = "1.0.2" |
|||
val h4sm = "0.0.17" |
|||
val http4s = "0.20.0-M5" |
|||
val logback = "1.2.3" |
|||
val monocle = "1.5.0" |
|||
val postgis = "1.3.3" |
|||
val postgres = "42.2.5" |
|||
val scalaCheck = "1.14.0" |
|||
val scalaTest = "3.0.5" |
|||
val simulacrum = "0.14.0" |
|||
|
|||
val httpDeps = Seq( |
|||
"http4s-blaze-server", |
|||
"http4s-blaze-client", |
|||
"http4s-circe", |
|||
"http4s-dsl" |
|||
).map("org.http4s" %% _ % http4s) ++ Seq( |
|||
"circe-core", |
|||
"circe-generic", |
|||
"circe-parser", |
|||
"circe-java8" |
|||
).map("io.circe" %% _ % circe) |
|||
|
|||
val testDeps = Seq( |
|||
"org.scalatest" %% "scalatest" % scalaTest, |
|||
"org.tpolecat" %% "doobie-scalatest" % doobie, |
|||
"org.scalacheck" %% "scalacheck" % scalaCheck, |
|||
"com.clovellytech" %% "h4sm-dbtesting" % h4sm |
|||
) |
|||
|
|||
val testDepsInTestOnly = testDeps.map(_ % "test") |
|||
|
|||
val dbDeps = Seq( |
|||
"org.flywaydb" % "flyway-core" % flyway, |
|||
"org.postgresql" % "postgresql" % postgres, |
|||
"org.postgis" % "postgis-jdbc" % postgis |
|||
) ++ Seq( |
|||
"doobie-core", |
|||
"doobie-postgres", |
|||
"doobie-hikari" |
|||
).map("org.tpolecat" %% _ % doobie) |
|||
|
|||
val commonDeps = Seq( |
|||
"io.circe" %% "circe-config" % circeConfig, |
|||
"ch.qos.logback" % "logback-classic" % logback, |
|||
"com.github.mpilquist" %% "simulacrum" % simulacrum |
|||
) ++ Seq( |
|||
"h4sm-auth", |
|||
"h4sm-files", |
|||
"h4sm-permissions" |
|||
).map("com.clovellytech" %% _ % h4sm) ++ Seq( |
|||
"monocle-core", |
|||
"monocle-generic", |
|||
"monocle-macro", |
|||
"monocle-state", |
|||
"monocle-refined" |
|||
).map("com.github.julien-truffaut" %% _ % monocle) |
|||
|
|||
val allDeps = httpDeps ++ dbDeps ++ commonDeps ++ testDepsInTestOnly |
|||
} |
@ -0,0 +1,58 @@ |
|||
|
|||
object options { |
|||
|
|||
val scalac = Seq( |
|||
// format: off |
|||
"-deprecation", // Emit warning and location for usages of deprecated APIs. |
|||
"-encoding", "utf-8", // Specify character encoding used by source files. |
|||
"-explaintypes", // Explain type errors in more detail. |
|||
"-feature", // Emit warning and location for usages of features that should be imported explicitly. |
|||
"-language:existentials", // Existential types (besides wildcard types) can be written and inferred |
|||
"-language:experimental.macros", // Allow macro definition (besides implementation and application) |
|||
"-language:higherKinds", // Allow higher-kinded types |
|||
"-language:implicitConversions", // Allow definition of implicit functions called views |
|||
"-unchecked", // Enable additional warnings where generated code depends on assumptions. |
|||
"-Xcheckinit", // Wrap field accessors to throw an exception on uninitialized access. |
|||
"-Xfatal-warnings", // Fail the compilation if there are any warnings. |
|||
"-Xfuture", // Turn on future language features. |
|||
"-Xlint:adapted-args", // Warn if an argument list is modified to match the receiver. |
|||
"-Xlint:by-name-right-associative", // By-name parameter of right associative operator. |
|||
"-Xlint:constant", // Evaluation of a constant arithmetic expression results in an error. |
|||
"-Xlint:delayedinit-select", // Selecting member of DelayedInit. |
|||
"-Xlint:doc-detached", // A Scaladoc comment appears to be detached from its element. |
|||
"-Xlint:inaccessible", // Warn about inaccessible types in method signatures. |
|||
"-Xlint:infer-any", // Warn when a type argument is inferred to be `Any`. |
|||
"-Xlint:missing-interpolator", // A string literal appears to be missing an interpolator id. |
|||
"-Xlint:nullary-override", // Warn when non-nullary `def f()' overrides nullary `def f'. |
|||
"-Xlint:nullary-unit", // Warn when nullary methods return Unit. |
|||
"-Xlint:option-implicit", // Option.apply used implicit view. |
|||
"-Xlint:package-object-classes", // Class or object defined in package object. |
|||
"-Xlint:poly-implicit-overload", // Parameterized overloaded implicit methods are not visible as view bounds. |
|||
"-Xlint:private-shadow", // A private field (or class parameter) shadows a superclass field. |
|||
"-Xlint:stars-align", // Pattern sequence wildcard must align with sequence component. |
|||
"-Xlint:type-parameter-shadow", // A local type parameter shadows a type already in scope. |
|||
"-Xlint:unsound-match", // Pattern match may not be typesafe. |
|||
"-Yno-adapted-args", // Do not adapt an argument list (either by inserting () or creating a tuple) to match the receiver. |
|||
"-Ypartial-unification", // Enable partial unification in type constructor inference |
|||
"-Ywarn-dead-code", // Warn when dead code is identified. |
|||
"-Ywarn-extra-implicit", // Warn when more than one implicit parameter section is defined. |
|||
"-Ywarn-inaccessible", // Warn about inaccessible types in method signatures. |
|||
"-Ywarn-infer-any", // Warn when a type argument is inferred to be `Any`. |
|||
"-Ywarn-nullary-unit", // Warn when nullary methods return Unit. |
|||
"-Ywarn-nullary-override", // Warn when non-nullary `def f()' overrides nullary `def f'. |
|||
"-Ywarn-numeric-widen", // Warn when numerics are widened. |
|||
"-Ywarn-unused:implicits", // Warn if an implicit parameter is unused. |
|||
"-Ywarn-unused:imports", // Warn if an import selector is not referenced. |
|||
"-Ywarn-unused:locals", // Warn if a local definition is unused. |
|||
"-Ywarn-unused:params", // Warn if a value parameter is unused. |
|||
"-Ywarn-unused:patvars", // Warn if a variable bound in a pattern is unused. |
|||
"-Ywarn-unused:privates", // Warn if a private member is unused. |
|||
"-Ywarn-value-discard", // Warn when non-Unit expression results are unused. |
|||
"-Yrangepos" |
|||
// format: on |
|||
) |
|||
|
|||
val badScalacConsoleFlags = Seq("-Xfatal-warnings", "-Ywarn-unused:imports") |
|||
|
|||
val scalacConsole = scalac.filterNot(badScalacConsoleFlags.contains(_)) |
|||
} |
@ -0,0 +1,4 @@ |
|||
object Version{ |
|||
val version = "0.0.1" |
|||
val scalaVersion = "2.12.8" |
|||
} |
@ -0,0 +1 @@ |
|||
sbt.version=1.2.3 |
@ -0,0 +1,4 @@ |
|||
addSbtPlugin("ch.epfl.scala" % "sbt-scalajs-bundler" % "0.13.1") |
|||
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.26") |
|||
addSbtPlugin("org.scalameta" % "sbt-mdoc" % "1.2.8" ) |
|||
addSbtPlugin("com.47deg" % "sbt-microsites" % "0.8.0") |
Write
Preview
Loading…
Cancel
Save
Reference in new issue