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

grist.GristClient.scala Maven / Gradle / Ivy

The newest version!
package grist

import io.circe.Json
import io.circe.syntax.EncoderOps
import zio.http.*
import zio.stream.UStream
import zio.{Chunk, Task, ZIO, ZLayer}

class GristClient(client: Client) extends Api(client) {
  object docs extends WithPath("docs") {
    def apply(docId: String) = new DocApi(docId)

    class DocApi(docId: String) extends WithPath(docId) {
      object tables extends WithPath("tables") {
        def apply(tableName: String) = new TableApi(tableName)

        def list = get[Models.Tables]()

        class TableApi(tableName: String) extends WithPath(tableName) {
          object records extends WithPath("records") {
            def list(filter: Map[String, Set[Json]]): Task[Models.Records] =
              get[Models.Records](QueryParams("filter" -> filter.asJson.noSpaces))

            def add(records: Models.RecordsWithoutId): Task[Models.RecordsWithoutFields] =
              postJson[Models.RecordsWithoutId, Models.RecordsWithoutFields](records)
          }

          object data extends WithPath("data") {
            object delete extends WithPath("delete") {
              def apply(ids: Set[Int]): Task[Unit] =
                postJson[Set[Int], Unit](ids)
            }
          }

          object columns extends WithPath("columns") {
            def list = get[Models.Columns]()
          }
        }
      }

      object attachments extends WithPath("attachments") {
        def upload(attachments: GristClient.AttachmentInfo*): Task[RefList] =
          ZIO.scoped {
            for {
              body     <- Body.fromMultipartFormUUID(
                            Form(
                              Chunk
                                .from(attachments)
                                .map { case GristClient.AttachmentInfo(data, mediaType, filename) =>
                                  FormField.streamingBinaryField("upload", data, mediaType, filename = filename)
                                }
                            )
                          )
              response <- baseClient.post("")(body)
              ids      <- parse[Seq[Int]](baseClient)(response)
            } yield RefList(ids)
          }
      }
    }
  }
}

//noinspection ScalaWeakerAccess
object GristClient {
  def forDomain(domain: String, apiToken: String): ZLayer[Client, Nothing, GristClient] =
    ZLayer.fromFunction { (client: Client) =>
      new GristClient(
        client
          .url(URL(kind = URL.Location.Absolute(Scheme.HTTPS, domain, None), path = Path.root / "api"))
          .addHeaders(Headers(Header.Authorization.Bearer(apiToken)))
      )
    }

  def apply(teamName: String, apiToken: String): ZLayer[Client, Nothing, GristClient] =
    forDomain(s"$teamName.getgrist.com", apiToken)

  def client = ZIO.service[GristClient]

  case class AttachmentInfo(data: UStream[Byte], mediaType: MediaType, filename: Option[String] = None)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy