-
Notifications
You must be signed in to change notification settings - Fork 421
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
668eb91
commit 78f5a8e
Showing
401 changed files
with
78,693 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package zio.http | ||
|
||
import scala.annotation.nowarn | ||
|
||
import zio.ZLayer | ||
|
||
@nowarn("msg=dead code") | ||
trait DriverPlatformSpecific { | ||
val default: ZLayer[Server.Config, Throwable, Driver] = | ||
throw new UnsupportedOperationException("Not implemented for Scala.js") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package zio.http | ||
|
||
import zio.Trace | ||
|
||
trait HandlerPlatformSpecific { | ||
self: Handler.type => | ||
|
||
def fromResource(path: String)(implicit trace: Trace): Handler[Any, Throwable, Any, Response] = | ||
throw new UnsupportedOperationException("Not supported on Scala.js") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package zio.http | ||
|
||
import scala.annotation.nowarn | ||
|
||
import zio._ | ||
|
||
import zio.http.Server.Config | ||
|
||
@nowarn("msg=dead code") | ||
trait ServerPlatformSpecific { | ||
val customized: ZLayer[Config, Throwable, Server] = | ||
throw new UnsupportedOperationException("Not implemented for Scala.js") | ||
|
||
val live: ZLayer[Config, Throwable, Server] = | ||
throw new UnsupportedOperationException("Not implemented for Scala.js") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package zio.http | ||
|
||
trait URLPlatformSpecific { | ||
self: URL => | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package zio.http | ||
|
||
import zio._ | ||
|
||
import zio.http.ZClient.Config | ||
import zio.http.internal.FetchDriver | ||
|
||
trait ZClientPlatformSpecific { | ||
|
||
def customized: ZLayer[Config with ZClient.Driver[Any, Scope, Throwable], Throwable, Client] = { | ||
implicit val trace: Trace = Trace.empty | ||
ZLayer.scoped { | ||
for { | ||
config <- ZIO.service[Config] | ||
driver <- ZIO.service[ZClient.Driver[Any, Scope, Throwable]] | ||
baseClient = ZClient.fromDriver(driver) | ||
} yield | ||
if (config.addUserAgentHeader) | ||
baseClient.addHeader(ZClient.defaultUAHeader) | ||
else | ||
baseClient | ||
} | ||
} | ||
|
||
def live: ZLayer[ZClient.Config, Throwable, Client] = { | ||
implicit val trace: Trace = Trace.empty | ||
FetchDriver.live >>> customized | ||
}.fresh | ||
|
||
def configured( | ||
path: NonEmptyChunk[String] = NonEmptyChunk("zio", "http", "client"), | ||
)(implicit trace: Trace): ZLayer[Any, Throwable, Client] = | ||
ZLayer(ZIO.config(Config.config.nested(path.head, path.tail: _*))) | ||
.mapError(error => new RuntimeException(s"Configuration error: $error")) >>> live | ||
|
||
def default: ZLayer[Any, Throwable, Client] = { | ||
implicit val trace: Trace = Trace.empty | ||
ZLayer.succeed(Config.default) >>> live | ||
} | ||
|
||
} |
97 changes: 97 additions & 0 deletions
97
js/src/main/scala/zio/http/codec/PathCodecPlatformSpecific.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package zio.http.codec | ||
|
||
trait PathCodecPlatformSpecific { | ||
private[codec] def parseLong(s: CharSequence, beginIndex: Int, endIndex: Int, radix: Int): Long = { | ||
require(s != null, "CharSequence cannot be null") | ||
checkFromToIndex(beginIndex, endIndex, s.length) | ||
|
||
if (radix < Character.MIN_RADIX) | ||
throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX") | ||
if (radix > Character.MAX_RADIX) | ||
throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX") | ||
var negative = false | ||
var i = beginIndex | ||
var limit = -Long.MaxValue | ||
if (i < endIndex) { | ||
val firstChar = s.charAt(i) | ||
if (firstChar < '0') { // Possible leading "+" or "-" | ||
if (firstChar == '-') { | ||
negative = true | ||
limit = Long.MinValue | ||
} else if (firstChar != '+') throw forCharSequence(s, beginIndex, endIndex, i) | ||
i += 1 | ||
} | ||
if (i >= endIndex) { // Cannot have lone "+", "-" or "" | ||
throw forCharSequence(s, beginIndex, endIndex, i) | ||
} | ||
val multmin = limit / radix | ||
var result = 0L | ||
while (i < endIndex) { | ||
// Accumulating negatively avoids surprises near MAX_VALUE | ||
val digit = Character.digit(s.charAt(i), radix) | ||
if (digit < 0 || result < multmin) throw forCharSequence(s, beginIndex, endIndex, i) | ||
result *= radix | ||
if (result < limit + digit) throw forCharSequence(s, beginIndex, endIndex, i) | ||
i += 1 | ||
result -= digit | ||
} | ||
if (negative) result | ||
else -result | ||
} else throw new NumberFormatException("") | ||
} | ||
|
||
private[codec] def parseInt(s: CharSequence, beginIndex: Int, endIndex: Int, radix: Int): Int = { | ||
require(s != null, "CharSequence cannot be null") | ||
checkFromToIndex(beginIndex, endIndex, s.length) | ||
|
||
if (radix < Character.MIN_RADIX) | ||
throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX") | ||
if (radix > Character.MAX_RADIX) | ||
throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX") | ||
var negative = false | ||
var i = beginIndex | ||
var limit = -Int.MaxValue | ||
if (i < endIndex) { | ||
val firstChar = s.charAt(i) | ||
if (firstChar < '0') { // Possible leading "+" or "-" | ||
if (firstChar == '-') { | ||
negative = true | ||
limit = Int.MinValue | ||
} else if (firstChar != '+') throw forCharSequence(s, beginIndex, endIndex, i) | ||
i += 1 | ||
if (i == endIndex) { // Cannot have lone "+" or "-" | ||
throw forCharSequence(s, beginIndex, endIndex, i) | ||
} | ||
} | ||
val multmin = limit / radix | ||
var result = 0 | ||
while (i < endIndex) { | ||
// Accumulating negatively avoids surprises near MAX_VALUE | ||
val digit = Character.digit(s.charAt(i), radix) | ||
if (digit < 0 || result < multmin) throw forCharSequence(s, beginIndex, endIndex, i) | ||
result *= radix | ||
if (result < limit + digit) throw forCharSequence(s, beginIndex, endIndex, i) | ||
i += 1 | ||
result -= digit | ||
} | ||
if (negative) result | ||
else -result | ||
} else throw forInputString("", radix) | ||
} | ||
|
||
private[codec] def forCharSequence(s: CharSequence, beginIndex: Int, endIndex: Int, errorIndex: Int) = | ||
new NumberFormatException( | ||
"Error at index " + (errorIndex - beginIndex) + " in: \"" + s.subSequence(beginIndex, endIndex) + "\"", | ||
) | ||
|
||
private[codec] def forInputString(s: String, radix: Int) = new NumberFormatException( | ||
"For input string: \"" + s + "\"" + (if (radix == 10) "" | ||
else " under radix " + radix), | ||
) | ||
|
||
private def checkFromToIndex(from: Int, to: Int, length: Int): Unit = { | ||
if (from < 0 || to > length || from > to) { | ||
throw new IndexOutOfBoundsException(s"Range [$from, $to) out of bounds for length $length") | ||
} | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
js/src/main/scala/zio/http/internal/BodyEncodingPlatformSpecific.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package zio.http.internal | ||
|
||
import scala.annotation.nowarn | ||
|
||
@nowarn("msg=dead code") | ||
trait BodyEncodingPlatformSpecific { | ||
val default: BodyEncoding = throw new NotImplementedError("No version implemented for Scala.js yet.") | ||
} |
8 changes: 8 additions & 0 deletions
8
js/src/main/scala/zio/http/internal/CookieEncodingPlatformSpecific.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package zio.http.internal | ||
|
||
import scala.annotation.nowarn | ||
|
||
@nowarn("msg=dead code") | ||
private[http] trait CookieEncodingPlatformSpecific { | ||
val default: CookieEncoding = throw new NotImplementedError("No version implemented for Scala.js yet.") | ||
} |
8 changes: 8 additions & 0 deletions
8
js/src/main/scala/zio/http/internal/DateEncodingPlatformSpecific.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package zio.http.internal | ||
|
||
import scala.annotation.nowarn | ||
|
||
@nowarn("msg=dead code") | ||
private[http] trait DateEncodingPlatformSpecific { | ||
val default: DateEncoding = throw new NotImplementedError("No version implemented for Scala.js yet.") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package zio.http.internal | ||
|
||
import scala.scalajs.js.typedarray.Uint8Array | ||
|
||
import zio._ | ||
|
||
import zio.stream.ZStream | ||
|
||
import zio.http._ | ||
|
||
import org.scalajs.dom.ReadableStream | ||
|
||
case class FetchBody( | ||
content: ReadableStream[Uint8Array], | ||
contentType: Option[Body.ContentType], | ||
) extends Body { | ||
|
||
/** | ||
* Returns an effect that decodes the content of the body as array of bytes. | ||
* Note that attempting to decode a large stream of bytes into an array could | ||
* result in an out of memory error. | ||
*/ | ||
override def asArray(implicit trace: Trace): Task[Array[Byte]] = | ||
ZIO.fromFuture { implicit ec => | ||
content.getReader().read().toFuture.map { value => | ||
value.value.map(_.toByte).toArray | ||
} | ||
} | ||
|
||
/** | ||
* Returns an effect that decodes the content of the body as a chunk of bytes. | ||
* Note that attempting to decode a large stream of bytes into a chunk could | ||
* result in an out of memory error. | ||
*/ | ||
override def asChunk(implicit trace: Trace): Task[Chunk[Byte]] = | ||
asArray.map(Chunk.fromArray) | ||
|
||
/** | ||
* Returns a stream that contains the bytes of the body. This method is safe | ||
* to use with large bodies, because the elements of the returned stream are | ||
* lazily produced from the body. | ||
*/ | ||
override def asStream(implicit trace: Trace): ZStream[Any, Throwable, Byte] = | ||
ZStream.fromIterableZIO(asChunk) | ||
|
||
/** | ||
* Returns whether or not the bytes of the body have been fully read. | ||
*/ | ||
override def isComplete: Boolean = | ||
false // Seems to not be possible to check this with Fetch API | ||
|
||
/** | ||
* Returns whether or not the content length is known | ||
*/ | ||
override def knownContentLength: Option[Long] = None | ||
|
||
/** | ||
* Returns whether or not the body is known to be empty. Note that some bodies | ||
* may not be known to be empty until an attempt is made to consume them. | ||
*/ | ||
override def isEmpty: Boolean = false | ||
|
||
/** | ||
* Updates the media type attached to this body, returning a new Body with the | ||
* updated media type | ||
*/ | ||
override def contentType(newContentType: Body.ContentType): Body = copy(contentType = Some(newContentType)) | ||
} | ||
|
||
object FetchBody { | ||
|
||
def fromResponse(result: org.scalajs.dom.Response, contentType: Option[Body.ContentType]): Body = { | ||
FetchBody(result.body, contentType) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package zio.http.internal | ||
|
||
import scala.collection.compat.immutable.ArraySeq | ||
import scala.scalajs.js | ||
import scala.scalajs.js.typedarray.Uint8Array | ||
|
||
import zio._ | ||
|
||
import zio.http._ | ||
|
||
import org.scalajs.dom | ||
import org.scalajs.dom.BodyInit | ||
|
||
final case class FetchDriver() extends ZClient.Driver[Any, Scope, Throwable] { | ||
override def request( | ||
version: Version, | ||
requestMethod: Method, | ||
url: URL, | ||
requestHeaders: Headers, | ||
requestBody: Body, | ||
sslConfig: Option[ClientSSLConfig], | ||
proxy: Option[Proxy], | ||
)(implicit trace: Trace): ZIO[Scope, Throwable, Response] = { | ||
for { | ||
jsBody <- fromZBody(requestBody) | ||
response <- | ||
ZIO.fromFuture { implicit ec => | ||
val jsMethod = fromZMethod(requestMethod) | ||
val jsHeaders = js.Dictionary(requestHeaders.map(h => h.headerName -> h.renderedValue).toSeq: _*) | ||
for { | ||
response <- dom | ||
.fetch( | ||
url.encode, | ||
new dom.RequestInit { | ||
method = jsMethod | ||
headers = jsHeaders | ||
body = jsBody | ||
}, | ||
) | ||
.toFuture | ||
} yield { | ||
val respHeaders = Headers.fromIterable(response.headers.map(h => Header.Custom(h(0), h(1)))) | ||
val ct = respHeaders.get(Header.ContentType) | ||
Response( | ||
status = Status.fromInt(response.status), | ||
headers = respHeaders, | ||
body = FetchBody.fromResponse(response, ct.map(Body.ContentType.fromHeader)), | ||
) | ||
} | ||
|
||
} | ||
} yield response | ||
} | ||
|
||
private def fromZMethod(method: Method): dom.HttpMethod = method match { | ||
case Method.GET => dom.HttpMethod.GET | ||
case Method.POST => dom.HttpMethod.POST | ||
case Method.PUT => dom.HttpMethod.PUT | ||
case Method.PATCH => dom.HttpMethod.PATCH | ||
case Method.DELETE => dom.HttpMethod.DELETE | ||
case Method.HEAD => dom.HttpMethod.HEAD | ||
case Method.OPTIONS => dom.HttpMethod.OPTIONS | ||
case Method.ANY => dom.HttpMethod.POST | ||
case Method.CUSTOM(name) => throw new IllegalArgumentException(s"Custom method $name is not supported") | ||
case Method.TRACE => throw new IllegalArgumentException("TRACE is not supported") | ||
case Method.CONNECT => throw new IllegalArgumentException("CONNECT is not supported") | ||
} | ||
|
||
private def fromZBody(body: Body): ZIO[Any, Throwable, js.UndefOr[BodyInit]] = | ||
if (body.isEmpty) { | ||
ZIO.succeed(js.undefined) | ||
} else { | ||
body.asArray.map { ar => Uint8Array.of(ArraySeq.unsafeWrapArray(ar.map(_.toShort)): _*) } | ||
} | ||
|
||
override def socket[Env1](version: Version, url: URL, headers: Headers, app: WebSocketApp[Env1])(implicit | ||
trace: Trace, | ||
ev: Scope =:= Scope, | ||
): ZIO[Env1 & Scope, Throwable, Response] = | ||
throw new UnsupportedOperationException("WebSockets are not supported in the js client yet.") | ||
|
||
} | ||
|
||
object FetchDriver { | ||
|
||
val live: ZLayer[Any, Nothing, FetchDriver] = | ||
ZLayer.succeed(FetchDriver()) | ||
|
||
} |
8 changes: 8 additions & 0 deletions
8
js/src/main/scala/zio/http/internal/HeaderEncodingPlatformSpecific.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package zio.http.internal | ||
|
||
import scala.annotation.nowarn | ||
|
||
@nowarn("msg=dead code") | ||
private[http] trait HeaderEncodingPlatformSpecific { | ||
val default: HeaderEncoding = throw new NotImplementedError("No version implemented for Scala.js yet.") | ||
} |
Oops, something went wrong.