All Downloads are FREE. Search and download functionalities are using the official Maven repository.

endpoints4s.fetch.Assets.scala Maven / Gradle / Ivy

The newest version!
package endpoints4s.fetch

import endpoints4s.algebra
import endpoints4s.algebra.Documentation
import org.scalajs.dom.HttpMethod

import scala.scalajs.js
import scala.scalajs.js.typedarray.ArrayBuffer

/** Client that relies on the web browser to handle gzip compression
  *
  * @group interpreters
  */
trait Assets extends algebra.Assets with EndpointsWithCustomErrors {

  /** As a client, we just need to give the path of the asset we are interested in, the web browser will
    * automatically set HTTP headers to handle gzip compression (`Accept-Encoding`) and decompress the response.
    */
  type AssetRequest = AssetPath

  /** {{{
    *   // foo/bar/baz-123abc
    *   AssetPath("foo/bar", "baz")
    * }}}
    */
  case class AssetPath(path: String, name: String)

  /** As we request the asset via a Fetch request, we get its content as an
    * `ArrayBuffer`
    */
  type AssetResponse = ArrayBuffer

  /** Convenient constructor for building an [[AssetRequest]] from its path and name.
    *
    * {{{
    *   myAssetsEndpoint(asset("foo/bar", "baz"))
    * }}}
    */
  def asset(path: String, name: String): AssetRequest = AssetPath(path, name)

  /** Encodes an [[AssetPath]] as a request path.
    * Throws an exception if the asset digest is not found.
    */
  // FIXME Check the asset digest in the `asset` smart constructor
  def assetSegments(name: String, docs: Documentation): Path[AssetPath] = {
    case AssetPath(path, name) =>
      val rawPath = s"$path/$name"
      val digest = digests.getOrElse(
        rawPath,
        throw new Exception(s"Asset not found: $rawPath")
      )
      s"$path/${js.URIUtils.encodeURIComponent(name)}-$digest"
  }

  /** An endpoint for requesting assets.
    *
    * If the server fails to find the requested asset, this endpoint returns
    * a failed response.
    *
    * @param url URL description
    * @return An HTTP endpoint for requesting assets
    */
  def assetsEndpoint(
      url: Url[AssetPath],
      docs: Documentation,
      notFoundDocs: Documentation
  ): Endpoint[AssetRequest, AssetResponse] =
    endpoint(arrayBufferGet(url), arrayBufferResponse)

  private def arrayBufferGet(url: Url[AssetPath]): Request[AssetRequest] =
    new Request[AssetRequest] {
      def apply(assetRequest: AssetRequest): RequestData =
        RequestData(HttpMethod.GET, _ => (), _ => ())
      def href(assetRequest: AssetRequest): String = url.encode(assetRequest)
    }

  private def arrayBufferResponse: Response[ArrayBuffer] =
    ok { fetchResponse =>
      fetchResponse
        .arrayBuffer()
        .`then`[Either[Throwable, ArrayBuffer]]((arrayBuffer: ArrayBuffer) => Right(arrayBuffer))
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy