penpot/backend/src/app/rpc/helpers.clj
2023-11-27 14:25:12 +01:00

80 lines
2.2 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.rpc.helpers
"General purpose RPC helpers."
(:refer-clojure :exclude [with-meta])
(:require
[app.common.data.macros :as dm]
[app.http :as-alias http]
[app.rpc :as-alias rpc]
[ring.response :as-alias rres]))
;; A utilty wrapper object for wrap service responses that does not
;; implements the IObj interface that make possible attach metadata to
;; it.
(deftype MetadataWrapper [obj ^:unsynchronized-mutable metadata]
clojure.lang.IDeref
(deref [_] obj)
clojure.lang.IObj
(withMeta [_ meta]
(MetadataWrapper. obj meta))
(meta [_] metadata))
(defn wrap
"Conditionally wrap a value into MetadataWrapper instance. If the
object already implements IObj interface it will be returned as is."
([] (wrap nil))
([o]
(if (instance? clojure.lang.IObj o)
o
(MetadataWrapper. o {})))
([o m]
(if (instance? clojure.lang.IObj o)
(vary-meta o merge m)
(MetadataWrapper. o m))))
(defn wrapped?
[o]
(instance? MetadataWrapper o))
(defn unwrap
[o]
(if (wrapped? o) @o o))
(defn with-header
"Add a http header to the RPC result."
[mdw key val]
(vary-meta mdw update ::http/headers assoc key val))
(defn with-transform
"Adds a http response transform to the RPC result."
[mdw transform-fn]
(vary-meta mdw update ::rpc/response-transform-fns conj transform-fn))
(defn with-defer
"Defer execution of the function until request is finished."
[mdw hook-fn]
(vary-meta mdw update ::rpc/before-complete-fns conj hook-fn))
(defn with-meta
[mdw mdata]
(vary-meta mdw merge mdata))
(defn assoc-meta
[mdw k v]
(vary-meta mdw assoc k v))
(defn with-http-cache
[mdw max-age]
(vary-meta mdw update ::rpc/response-transform-fns conj
(fn [_ response]
(let [exp (if (integer? max-age) max-age (inst-ms max-age))
val (dm/fmt "max-age=%" (int (/ exp 1000.0)))]
(update response ::rres/headers assoc "cache-control" val)))))