penpot/frontend/src/app/main/repo.cljs
2023-01-18 10:51:58 +01:00

193 lines
6 KiB
Clojure

;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) KALEIDOS INC
(ns app.main.repo
(:require
[app.common.data :as d]
[app.common.uri :as u]
[app.config :as cf]
[app.util.http :as http]
[beicon.core :as rx]))
(derive :get-file ::query)
(derive :get-file-object-thumbnails ::query)
(derive :get-file-libraries ::query)
(derive :get-file-fragment ::query)
(derive :search-files ::query)
(derive :get-teams ::query)
(derive :get-team-users ::query)
(derive :get-team-members ::query)
(derive :get-team-stats ::query)
(derive :get-team-invitations ::query)
(derive :get-team-shared-files ::query)
(defn handle-response
[{:keys [status body] :as response}]
(cond
(= 204 status)
;; We need to send "something" so the streams listening downstream can act
(rx/of nil)
(= 502 status)
(rx/throw {:type :bad-gateway})
(= 503 status)
(rx/throw {:type :service-unavailable})
(= 0 (:status response))
(rx/throw {:type :offline})
(= 200 status)
(rx/of body)
(= 413 status)
(rx/throw {:type :validation
:code :request-body-too-large})
(and (>= status 400) (map? body))
(rx/throw body)
:else
(rx/throw {:type :unexpected-error
:status status
:data body})))
(defn- send-query!
"A simple helper for send and receive transit data on the penpot
query api."
([id params]
(send-query! id params nil))
([id params {:keys [raw-transit?]}]
(let [decode-transit (if raw-transit?
http/conditional-error-decode-transit
http/conditional-decode-transit)]
(->> (http/send! {:method :get
:uri (u/join @cf/public-uri "api/rpc/query/" (name id))
:headers {"accept" "application/transit+json"}
:credentials "include"
:query params})
(rx/map decode-transit)
(rx/mapcat handle-response)))))
(defn- send-mutation!
"A simple helper for a common case of sending and receiving transit
data to the penpot mutation api."
[id params]
(->> (http/send! {:method :post
:uri (u/join @cf/public-uri "api/rpc/mutation/" (name id))
:headers {"accept" "application/transit+json"}
:credentials "include"
:body (http/transit-data params)})
(rx/map http/conditional-decode-transit)
(rx/mapcat handle-response)))
(defn- send-command!
"A simple helper for a common case of sending and receiving transit
data to the penpot mutation api."
[id params {:keys [response-type form-data? raw-transit?]}]
(let [decode-fn (if raw-transit?
http/conditional-error-decode-transit
http/conditional-decode-transit)
method (if (isa? id ::query) :get :post)]
(->> (http/send! {:method method
:uri (u/join @cf/public-uri "api/rpc/command/" (name id))
:credentials "include"
:headers {"accept" "application/transit+json"}
:body (when (= method :post)
(if form-data?
(http/form-data params)
(http/transit-data params)))
:query (when (= method :get)
params)
:response-type (or response-type :text)})
(rx/map decode-fn)
(rx/mapcat handle-response))))
(defn- dispatch [& args] (first args))
(defmulti query dispatch)
(defmulti mutation dispatch)
(defmulti command dispatch)
(defmethod query :default
[id params]
(send-query! id params))
(defmethod command :get-raw-file
[_id params]
(send-command! :get-file params {:raw-transit? true}))
(defmethod mutation :default
[id params]
(send-mutation! id params))
(defmethod command :default
[id params]
(send-command! id params nil))
(defmethod command :export-binfile
[id params]
(send-command! id params {:response-type :blob}))
(defmethod command :import-binfile
[id params]
(send-command! id params {:form-data? true}))
(defn query!
([id] (query id {}))
([id params] (query id params)))
(defn mutation!
([id] (mutation id {}))
([id params] (mutation id params)))
(defn command!
([id] (command id {}))
([id params] (command id params)))
(defn cmd!
([id] (command id {}))
([id params] (command id params)))
(defmethod command :login-with-oidc
[_ {:keys [provider] :as params}]
(let [uri (u/join @cf/public-uri "api/auth/oauth/" (d/name provider))
params (dissoc params :provider)]
(->> (http/send! {:method :post
:uri uri
:credentials "include"
:query params})
(rx/map http/conditional-decode-transit)
(rx/mapcat handle-response))))
(defn- send-export
[{:keys [blob?] :as params}]
(->> (http/send! {:method :post
:uri (u/join @cf/public-uri "api/export")
:body (http/transit-data (dissoc params :blob?))
:credentials "include"
:response-type (if blob? :blob :text)})
(rx/map http/conditional-decode-transit)
(rx/mapcat handle-response)))
(defmethod command :export
[_ params]
(let [default {:wait false :blob? false}]
(send-export (merge default params))))
(derive :upload-file-media-object ::multipart-upload)
(derive :update-profile-photo ::multipart-upload)
(derive :update-team-photo ::multipart-upload)
(defmethod mutation ::multipart-upload
[id params]
(->> (http/send! {:method :post
:uri (u/join @cf/public-uri "api/rpc/mutation/" (name id))
:credentials "include"
:body (http/form-data params)})
(rx/map http/conditional-decode-transit)
(rx/mapcat handle-response)))