Releases: kevin-lee/refined4s
v1.1.0
v1.0.0
1.0.0 - 2024-11-02
Breaking Change
-
Fix: Scala.js support is broken (#370)
To fix it, the following changes were made:
-
Added
scalajs-java-securerandom
to usejava.security.SecureRandom
forjava.util.UUID
scala-java-time
forjava.time
in Scala.js- a custom URL implementation for Scala.js because there's no alternative to
java.net.URL
-
Made other necessary changes, including removing code unavailable in JavaScript.
-
Fixed the tests for JavaScript. There were issues with
Long
andBigInt
values less than-9007199254740991L
and greater than9007199254740991L
.
-
v0.19.0
0.19.0 - 2024-09-01
New Features
- [
refined4s-circe
] AddKeyEncoder
,KeyDecoder
andKeyCodec
forNewtype
andRefined
(#355)
-
[
refined4s-core
] AddtoUrl
toUri
, and addtoUri
totoUrl
(#356)Uri("https://www.google.com").toUrl // Url("https://www.google.com") Url("https://www.google.com").toUri // Uri("https://www.google.com")
-
[
refined4s-core
] AddtoURL
toUri
, and addtoURI
totoUrl
(#358)Uri("https://www.google.com").toURL // java.net.URL("https://www.google.com") Url("https://www.google.com").toURI // java.net.URI("https://www.google.com")
- [
refined4s-circe
] AddKeyEncoder
andKeyDecoder
for pre-defined refined types (#361)
-
[
refined4s-circe
] AddKeyEncoder
andKeyDecoder
torefined4s.modules.circe.derivation.generic.auto
(#369)Thanks to @ivan-klass for the
KeyEncoder
andKeyDecoder
request and PR (#353).
-
Update sbt plugins (#372)
sbt-ci-release
to1.6.1
sbt-wartremover
to3.2.0
sbt-scalafix
to0.12.1
sbt-scalafmt
to2.5.2
sbt-scoverage
to2.1.1
sbt-mdoc
to2.5.4
sbt-docusaur
to0.16.0
sbt-tpolecat
to0.5.2
com.github.xuwei-k:scalafix-rules
to0.4.5
- Update GitHub Actions: Update
javaOptions
(#376)env: GH_SBT_OPTS: "-Xss64m -Xms1024m -Xmx8G -XX:MaxMetaspaceSize=2G -XX:-UseGCOverheadLimit -XX:MaxInlineLevel=18 -XX:+UnlockExperimentalVMOptions" GH_JVM_OPTS: "-Xss64m -Xms1024m -Xmx8G -XX:MaxMetaspaceSize=2G -XX:-UseGCOverheadLimit -XX:MaxInlineLevel=18 -XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler"
- [
refined4s-refined-compat-scala2
] Bump Scala2.12
to2.12.16
(#379)
v0.18.0
0.18.0 - 2024-08-18
New Features
refined4s-chimney
Add missing type-classes for Chimney
-
[
refined4s-chimney
] Add missingTransformer
to unwrap value forChimneyNewtype
(#340)import refined4s.* import refined4s.modules.chimney.derivation.* final case class Person(name: Person.Name) object Person { type Name = Name.Type object Name extends Newtype[String], ChimneyNewtype[String] } final case class User(name: String) import io.scalaland.chimney.* import io.scalaland.chimney.dsl.* val person = Person(Person.Name("Wade Wilson")) val deadpool = person.transformInto[User] // This is currently not possible.
-
[
refined4s-chimney
] Add missingTransformer
to unwrap value forChimneyRefined
(#341)import refined4s.* import refined4s.modules.chimney.derivation.* final case class Person(name: Person.NotEmptyStr) object Person { type NotEmptyStr = NotEmptyStr.Type object NotEmptyStr extends Refined[String], ChimneyRefined[String] { inline def invalidReason(a: String): String = "non-empty String" inline def predicate(a: String): Boolean = a != "" } } final case class User(name: String) import io.scalaland.chimney.* import io.scalaland.chimney.dsl.* val person = Person(Person.NotEmptyStr("Wade Wilson")) val deadpool = person.transformInto[User] // This was not possible.
-
[
refined4s-chimney
] AddPartialTransformer
to transformRefined[A]
toNewtype[Refined[A]]
forChimneyRefined
(#342)import refined4s.* import refined4s.modules.chimney.derivation.* import io.scalaland.chimney.* import io.scalaland.chimney.dsl.* final case class XMen(name: XMen.NotEmptyStr) object XMen { type NotEmptyStr = NotEmptyStr.Type object NotEmptyStr extends Refined[String], ChimneyRefined[String] { inline def invalidReason(a: String): String = "non-empty String" inline def predicate(a: String): Boolean = a != "" } } import refined4s.types.all.* final case class MarvelCharacter(name: MarvelCharacter.Name) object MarvelCharacter { type Name = Name.Type object Name extends Newtype[NonEmptyString], ChimneyNewtype[NonEmptyString] } val logan = XMen(XMen.NotEmptyStr("James Howlett")) import refined4s.modules.chimney.derivation.types.all.* val wolverine = logan.transformIntoPartial[MarvelCharacter]
-
[
refined4s-chimney
] AddPartialTransformer
to transformNewtype[A]
toNewtype[Refined[A]]
forChimneyNewtype
(#346)import refined4s.* import refined4s.modules.chimney.derivation.* import io.scalaland.chimney.* import io.scalaland.chimney.dsl.* final case class XMen(name: XMen.Name) object XMen { type Name = Name.Type object Name extends Newtype[String], ChimneyNewtype[String] } import refined4s.types.all.* final case class MarvelCharacter(name: MarvelCharacter.Name) object MarvelCharacter { type Name = Name.Type object Name extends Newtype[NonEmptyString], ChimneyNewtype[NonEmptyString] } val logan = XMen(XMen.Name("James Howlett")) import refined4s.modules.chimney.derivation.types.all.* val wolverine = logan.transformIntoPartial[MarvelCharacter]
v0.17.0
0.17.0 - 2024-08-11
New Features
Add refined4s-chimney
refined4s.modules.chimney.derivation.generic.auto
- [
refined4s-chimney
] Addrefined4s.modules.chimney.derivation.generic.auto
for auto derivation for Chimney (#325)
import io.scalaland.chimney
import refined4s.modules.chimney.derivation.generic.auto.given
import refined4s.types.all.PosInt
import refined4s.{Newtype, Refined}
val emailRegEx =
"""([a-zA-Z0-9]+([-_\.\+]+[a-zA-Z0-9]+)*@[a-zA-Z0-9]+([-_]+[a-zA-Z0-9]+)*(?:[.][a-zA-Z0-9]+([-_]+[a-zA-Z0-9]+)*)+)""".r
final case class Foo(id: Foo.Id, baz: Foo.Baz)
object Foo {
type Id = Id.Type
object Id extends Newtype[PosInt]
type Name = Name.Type
object Name extends Newtype[String]
type Email = Email.Type
object Email extends Refined[String] {
override def invalidReason(a: String): String = s"Invalid email: $a"
override def predicate(a: String): Boolean = emailRegEx.findFirstMatchIn(a).isDefined
}
final case class Baz(name: Name, email: Email)
}
final case class Bar(id: Bar.Code, baz: Bar.Baz)
object Bar {
type Code = Code.Type
object Code extends Newtype[PosInt]
type Label = Label.Type
object Label extends Newtype[String]
type Email = Email.Type
object Email extends Refined[String] {
override def invalidReason(a: String): String = s"Invalid email: $a"
override def predicate(a: String): Boolean = emailRegEx.findFirstMatchIn(a).isDefined
}
final case class Baz(name: Label, email: Email)
}
val id = Foo.Id(PosInt(123))
id.into[Bar.Code].transform
// Bar.Code(PosInt(123))
val name = Foo.Name("Kevin")
name.into[Bar.Label].transform
// Bar.Label("Kevin")
val email = Foo.Email("[email protected]")
email.intoPartial[Bar.Email].transform
// Result[Bar.Email] = Value(Bar.Email("[email protected]"))
Foo(id, Foo.Baz(name, email).intoPartial[Bar].transform
// Result[Bar] = Value(Bar(id = Code(PosInt(123)), Bar.Baz(name = Bar.Label("Kevin"), Bar.Email("[email protected]"))))
refined4s.modules.chimney.derivation.ChimneyNewtype
- [
refined4s-chimney
] Addrefined4s.modules.chimney.derivation.ChimneyNewtype
forNewtype
derivation for Chimney (#326)
import refined4s.Newtype
import refined4s.types.all.PosInt
import refined4s.modules.chimney.derivation.*
type Id = Id.Type
object Id extends Newtype[PosInt], ChimneyNewtype[PosInt]
type Name = Name.Type
object Name extends Newtype[String], ChimneyNewtype[String]
refined4s.modules.chimney.derivation.ChimneyRefined
- [
refined4s-chimney
] Addrefined4s.modules.chimney.derivation.ChimneyRefined
forRefined
derivation for Chimney (#327)
import refined4s.types.all.*
import refined4s.Refined
import refined4s.modules.chimney.derivation.*
type Email = Email.Type
object Email extends Refined[String], ChimneyRefined[String] {
val emailRegEx =
"""([a-zA-Z0-9]+([-_\.\+]+[a-zA-Z0-9]+)*@[a-zA-Z0-9]+([-_]+[a-zA-Z0-9]+)*(?:[.][a-zA-Z0-9]+([-_]+[a-zA-Z0-9]+)*)+)""".r
override def invalidReason(a: String): String = s"Invalid email: $a"
override def predicate(a: String): Boolean = emailRegEx.findFirstMatchIn(a).isDefined
}
refined4s.modules.chimney.derivation.types.strings
- [
refined4s-chimney
] Addrefined4s.modules.chimney.derivation.types.strings
to support Chimney for pre-defined refined types inrefined4s.types.strings
(#331)
import refined4s.modules.chimney.derivation.types.strings.given
refined4s.modules.chimney.derivation.types.numeric
- [
refined4s-chimney
] Addrefined4s.modules.chimney.derivation.types.numeric
to support Chimney for pre-defined refined types inrefined4s.types.numeric
(#332)
import refined4s.modules.chimney.derivation.types.numeric.given
refined4s.modules.chimney.derivation.types.network
- [
refined4s-chimney
] Addrefined4s.modules.chimney.derivation.types.network
to support Chimney for pre-defined refined types inrefined4s.types.network
(#333)
import refined4s.modules.chimney.derivation.types.network.given
refined4s.modules.chimney.derivation.types.all
- [
refined4s-chimney
] Addrefined4s.modules.chimney.derivation.types.all
to support Chimney for pre-defined refined types inrefined4s.types.all
(#334)
It's for all pre-defined types in strings
, numeric
and network
.
import refined4s.modules.chimney.derivation.types.all.given
Internal Housekeeping
- Bump Scala to 3.3.3, the latest Long-Term Support (LTS) version (#319)
v0.16.0
0.16.0 - 2024-08-03
Improvement
- [
refined4s-core
] Add unicode encoding for the error message fromNonBlankString.from
(#312)val s = "\u0009\u200a\u2004\u1680" // String = " " NonBlankString.from(s) // Left(Invalid value: [ ], unicode=[\u0009\u200a\u2004\u1680]. It must be not all whitespace non-empty String)
- [
refined4s-circe
] Addnumeric
,strings
andnetwork
objects inrefined4s.modules.circe.derivation.types
v0.15.0
0.15.0 - 2024-04-13
New Features
-
[
refined4s-core
] AddNonBlankString
which can be neither all whitespace chars nor an empty String (#281)NonBlankString("") // Invalid value: [""]. It must be not all whitespace non-empty String NonBlankString(" ") // Invalid value: [" "]. It must be not all whitespace non-empty String NonBlankString(" ") // Invalid value: [" "]. It must be not all whitespace non-empty String NonBlankString("\n") // Invalid value: ["\n"]. It must be not all whitespace non-empty String NonBlankString("\t") // Invalid value: ["\t"]. It must be not all whitespace non-empty String NonBlankString("\t\n") // Invalid value: ["\t\n"]. It must be not all whitespace non-empty String NonBlankString(" \t \n") // Invalid value: [" \t \n"]. It must be not all whitespace non-empty String
-
[
refined4s-cats
] Addcats
support forNonBlankString
(#283) -
[
refined4s-circe
] Addcirce
support forNonBlankString
(#284) -
[
refined4s-pureconfig
] Addpureconfig
support forNonBlankString
(#285) -
[
refined4s-doobie
] Adddoobie
support forNonBlankString
(#286) -
[
refined4s-extras-render
] Addextras-render
support forNonBlankString
(#287) -
[
refined4s-tapir
] Addtapir
support forNonBlankString
(#288)
v0.14.0
0.14.0 - 2024-04-05
New Features
- Add
refined4s-tapir
to supporttapir
(#272) - [
refined4s-tapir
] AddTapirNewtypeSchema
andTapirRefinedSchema
to supportsttp.tapir.Schema
forrefined4s
(#273) - [
refined4s-tapir
] AddSchema
s for pre-defined refined types (#276) - [
refined4s-tapir
] AddSchema
type-class instances with auto deriving (#278)
v0.13.0
0.13.0 - 2024-01-21
New Features
- [
refined4s-core
] AddUrl
torefined4s.types.network
and the type-class instances forUrl
in the other modules (#246)
- [
refined4s-core
] AddUuid
String
which can be validated asjava.util.UUID
and the type-class instances forUuid
in the other modules (#248)
- [
refined4s-core
] AddUri.apply(java.net.URI)
(#251)
- [
refined4s-core
] AddUrl.apply(java.net.URL)
(#252)
- [
refined4s-refined-compat-scala2
] AddUri
,Url
andUuid
(#255)
v0.12.0
0.12.0 - 2024-01-20
New Feature
-
[
refined4s-core
] Make pre-defined types intypes.all
importable from each type category (i.e.numeric
,strings
andnetwork
) (#237)So it means a type like
refined4s.types.numeric.NegInt
should be exactly the same asrefined4s.types.all.NegInt
.
- Add
refined4s-refined-compat
modules for compatibility with therefined
library in Scala 2 (#241)refined4s-refined-compat-scala2
for compatibility withrefined
in Scala 2refined4s-refined-compat-scala3
for just usingrefined4s
in Scala 3
- Add
RefinedCompatAllTypes
torefined4s-refined-compat-scala2
andrefined4s-refined-compat-scala3
(#243)
Internal Change
-
[
refined4s-core
] MoveMinValue
andMaxValue
from eachMinMax
toMin
andMax
(#239)e.g.)
type NegInt = NegInt.Type object NegInt extends Numeric[Int], MinMax[Int] { override def min: Type = apply(Int.MinValue) override def max: Type = apply(-1) val MinValue: Type = min val MaxValue: Type = max }
to
trait Min[A] { self: NewtypeBase[A] => def min: Type val MinValue: Type = min } trait Max[A] { self: NewtypeBase[A] => def max: Type val MaxValue: Type = max }