mirror of
https://github.com/penpot/penpot.git
synced 2025-02-14 19:19:09 -05:00
♻️ Clean assertion and schema chechking API
This commit is contained in:
parent
45f3a67950
commit
002b1679c3
13 changed files with 161 additions and 168 deletions
|
@ -278,25 +278,18 @@
|
||||||
:inc 1)
|
:inc 1)
|
||||||
message)
|
message)
|
||||||
|
|
||||||
(def ^:private schema:params
|
|
||||||
[:map {:title "params"}
|
|
||||||
[:session-id ::sm/uuid]])
|
|
||||||
|
|
||||||
(def ^:private decode-params
|
|
||||||
(sm/decoder schema:params sm/json-transformer))
|
|
||||||
|
|
||||||
(def ^:private validate-params!
|
|
||||||
(sm/validate-fn schema:params))
|
|
||||||
|
|
||||||
(defn- http-handler
|
(defn- http-handler
|
||||||
[cfg {:keys [params ::session/profile-id] :as request}]
|
[cfg {:keys [params ::session/profile-id] :as request}]
|
||||||
(let [{:keys [session-id]} (-> params
|
(let [session-id (some-> params :session-id sm/parse-uuid)]
|
||||||
decode-params
|
(when-not (uuid? session-id)
|
||||||
validate-params!)]
|
(ex/raise :type :validation
|
||||||
|
:code :missing-session-id
|
||||||
|
:hint "missing or invalid session-id found"))
|
||||||
|
|
||||||
(cond
|
(cond
|
||||||
(not profile-id)
|
(not profile-id)
|
||||||
(ex/raise :type :authentication
|
(ex/raise :type :authentication
|
||||||
:hint "Authentication required.")
|
:hint "authentication required")
|
||||||
|
|
||||||
;; WORKAROUND: we use the adapter specific predicate for
|
;; WORKAROUND: we use the adapter specific predicate for
|
||||||
;; performance reasons; for now, the ring default impl for
|
;; performance reasons; for now, the ring default impl for
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.exceptions :as ex]
|
||||||
[app.common.logging :as l]
|
[app.common.logging :as l]
|
||||||
[app.common.schema :as sm]
|
[app.common.schema :as sm]
|
||||||
[app.http.client :as http]
|
[app.http.client :as http]
|
||||||
|
@ -19,26 +20,26 @@
|
||||||
[datoteka.fs :as fs]
|
[datoteka.fs :as fs]
|
||||||
[integrant.core :as ig]))
|
[integrant.core :as ig]))
|
||||||
|
|
||||||
(def ^:private
|
(def ^:private schema:template
|
||||||
schema:template
|
|
||||||
[:map {:title "Template"}
|
[:map {:title "Template"}
|
||||||
[:id ::sm/word-string]
|
[:id ::sm/word-string]
|
||||||
[:name ::sm/word-string]
|
[:name ::sm/word-string]
|
||||||
[:file-uri ::sm/word-string]])
|
[:file-uri ::sm/word-string]])
|
||||||
|
|
||||||
(def ^:private
|
(def ^:private schema:templates
|
||||||
schema:templates
|
|
||||||
[:vector schema:template])
|
[:vector schema:template])
|
||||||
|
|
||||||
|
(def check-templates!
|
||||||
|
(sm/check-fn schema:templates
|
||||||
|
:code :invalid-templates
|
||||||
|
:hint "invalid templates"))
|
||||||
|
|
||||||
(defmethod ig/init-key ::setup/templates
|
(defmethod ig/init-key ::setup/templates
|
||||||
[_ _]
|
[_ _]
|
||||||
(let [templates (-> "app/onboarding.edn" io/resource slurp edn/read-string)
|
(let [templates (-> "app/onboarding.edn" io/resource slurp edn/read-string)
|
||||||
|
templates (check-templates! templates)
|
||||||
dest (fs/join fs/*cwd* "builtin-templates")]
|
dest (fs/join fs/*cwd* "builtin-templates")]
|
||||||
|
|
||||||
(dm/verify!
|
|
||||||
"expected a valid templates file"
|
|
||||||
(sm/check! schema:templates templates))
|
|
||||||
|
|
||||||
(doseq [{:keys [id path] :as template} templates]
|
(doseq [{:keys [id path] :as template} templates]
|
||||||
(let [path (or path (fs/join dest id))]
|
(let [path (or path (fs/join dest id))]
|
||||||
(if (fs/exists? path)
|
(if (fs/exists? path)
|
||||||
|
@ -58,9 +59,9 @@
|
||||||
(let [resp (http/req! cfg
|
(let [resp (http/req! cfg
|
||||||
{:method :get :uri (:file-uri template)}
|
{:method :get :uri (:file-uri template)}
|
||||||
{:response-type :input-stream :sync? true})]
|
{:response-type :input-stream :sync? true})]
|
||||||
|
(when-not (= 200 (:status resp))
|
||||||
(dm/verify!
|
(ex/raise :type :internal
|
||||||
"unexpected response found on fetching template"
|
:code :unexpected-status-code
|
||||||
(= 200 (:status resp)))
|
:hint (str "unable to download template, recevied status " (:status resp))))
|
||||||
|
|
||||||
(io/input-stream (:body resp)))))))
|
(io/input-stream (:body resp)))))))
|
||||||
|
|
|
@ -155,9 +155,10 @@
|
||||||
|
|
||||||
(defn enable-team-feature!
|
(defn enable-team-feature!
|
||||||
[team-id feature]
|
[team-id feature]
|
||||||
(dm/verify!
|
(when-not (contains? cfeat/supported-features feature)
|
||||||
"feature should be supported"
|
(ex/raise :type :assertion
|
||||||
(contains? cfeat/supported-features feature))
|
:code :feature-not-supported
|
||||||
|
:hint (str "feature '" feature "' not supported")))
|
||||||
|
|
||||||
(let [team-id (h/parse-uuid team-id)]
|
(let [team-id (h/parse-uuid team-id)]
|
||||||
(db/tx-run! main/system
|
(db/tx-run! main/system
|
||||||
|
@ -173,9 +174,11 @@
|
||||||
|
|
||||||
(defn disable-team-feature!
|
(defn disable-team-feature!
|
||||||
[team-id feature]
|
[team-id feature]
|
||||||
(dm/verify!
|
|
||||||
"feature should be supported"
|
(when-not (contains? cfeat/supported-features feature)
|
||||||
(contains? cfeat/supported-features feature))
|
(ex/raise :type :assertion
|
||||||
|
:code :feature-not-supported
|
||||||
|
:hint (str "feature '" feature "' not supported")))
|
||||||
|
|
||||||
(let [team-id (h/parse-uuid team-id)]
|
(let [team-id (h/parse-uuid team-id)]
|
||||||
(db/tx-run! main/system
|
(db/tx-run! main/system
|
||||||
|
@ -203,9 +206,11 @@
|
||||||
[{:keys [::mbus/msgbus ::db/pool]} & {:keys [dest code message level]
|
[{:keys [::mbus/msgbus ::db/pool]} & {:keys [dest code message level]
|
||||||
:or {code :generic level :info}
|
:or {code :generic level :info}
|
||||||
:as params}]
|
:as params}]
|
||||||
(dm/verify!
|
|
||||||
["invalid level %" level]
|
(when-not (contains? #{:success :error :info :warning} level)
|
||||||
(contains? #{:success :error :info :warning} level))
|
(ex/raise :type :assertion
|
||||||
|
:code :incorrect-level
|
||||||
|
:hint (str "level '" level "' not supported")))
|
||||||
|
|
||||||
(letfn [(send [dest]
|
(letfn [(send [dest]
|
||||||
(l/inf :hint "sending notification" :dest (str dest))
|
(l/inf :hint "sending notification" :dest (str dest))
|
||||||
|
|
|
@ -108,14 +108,6 @@
|
||||||
`(do ~@body)
|
`(do ~@body)
|
||||||
(reverse (partition 2 bindings))))
|
(reverse (partition 2 bindings))))
|
||||||
|
|
||||||
(defmacro check
|
|
||||||
"Applies a predicate to the value, if result is true, return the
|
|
||||||
value if not, returns nil."
|
|
||||||
[pred-fn value]
|
|
||||||
`(if (~pred-fn ~value)
|
|
||||||
~value
|
|
||||||
nil))
|
|
||||||
|
|
||||||
(defmacro get-prop
|
(defmacro get-prop
|
||||||
"A macro based, optimized variant of `get` that access the property
|
"A macro based, optimized variant of `get` that access the property
|
||||||
directly on CLJS, on CLJ works as get."
|
directly on CLJS, on CLJ works as get."
|
||||||
|
@ -124,47 +116,32 @@
|
||||||
(list 'js* (c/str "(~{}?." (str/snake prop) "?? ~{})") obj (list 'cljs.core/get obj prop))
|
(list 'js* (c/str "(~{}?." (str/snake prop) "?? ~{})") obj (list 'cljs.core/get obj prop))
|
||||||
(list `c/get obj prop)))
|
(list `c/get obj prop)))
|
||||||
|
|
||||||
(def ^:dynamic *assert-context* nil)
|
(defn runtime-assert
|
||||||
|
[hint f]
|
||||||
|
(try
|
||||||
|
(when-not (f)
|
||||||
|
(throw (ex-info hint {:type :assertion
|
||||||
|
:code :expr-validation
|
||||||
|
:hint hint})))
|
||||||
|
(catch #?(:clj Throwable :cljs :default) cause
|
||||||
|
(let [data (-> (ex-data cause)
|
||||||
|
(assoc :type :assertion)
|
||||||
|
(assoc :code :expr-validation)
|
||||||
|
(assoc :hint hint))]
|
||||||
|
(throw (ex-info hint data cause))))))
|
||||||
|
|
||||||
(defmacro assert!
|
(defmacro assert!
|
||||||
([expr]
|
([expr]
|
||||||
`(assert! nil ~expr))
|
`(assert! nil ~expr))
|
||||||
([hint expr]
|
([hint expr]
|
||||||
(let [hint (cond
|
(let [hint (cond
|
||||||
(vector? hint)
|
(vector? hint)
|
||||||
`(str/ffmt ~@hint)
|
`(str/ffmt ~@hint)
|
||||||
|
|
||||||
(some? hint)
|
(some? hint)
|
||||||
hint
|
hint
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(str "expr assert: " (pr-str expr)))]
|
(str "expr assert: " (pr-str expr)))]
|
||||||
(when *assert*
|
(when *assert*
|
||||||
`(binding [*assert-context* ~hint]
|
`(runtime-assert ~hint (fn [] ~expr))))))
|
||||||
(when-not ~expr
|
|
||||||
(let [hint# ~hint
|
|
||||||
params# {:type :assertion
|
|
||||||
:code :expr-validation
|
|
||||||
:hint hint#}]
|
|
||||||
(throw (ex-info hint# params#)))))))))
|
|
||||||
|
|
||||||
(defmacro verify!
|
|
||||||
([expr]
|
|
||||||
`(verify! nil ~expr))
|
|
||||||
([hint expr]
|
|
||||||
(let [hint (cond
|
|
||||||
(vector? hint)
|
|
||||||
`(str/ffmt ~@hint)
|
|
||||||
|
|
||||||
(some? hint)
|
|
||||||
hint
|
|
||||||
|
|
||||||
:else
|
|
||||||
(str "expr assert: " (pr-str expr)))]
|
|
||||||
`(binding [*assert-context* ~hint]
|
|
||||||
(when-not ~expr
|
|
||||||
(let [hint# ~hint
|
|
||||||
params# {:type :assertion
|
|
||||||
:code :expr-validation
|
|
||||||
:hint hint#}]
|
|
||||||
(throw (ex-info hint# params#))))))))
|
|
||||||
|
|
|
@ -414,10 +414,11 @@
|
||||||
;; If object has changed or is new verify is correct
|
;; If object has changed or is new verify is correct
|
||||||
(when (and (some? shape-new)
|
(when (and (some? shape-new)
|
||||||
(not= shape-old shape-new))
|
(not= shape-old shape-new))
|
||||||
(dm/verify!
|
(when-not (and (cts/valid-shape? shape-new)
|
||||||
"expected valid shape"
|
(cts/shape? shape-new))
|
||||||
(and (cts/valid-shape? shape-new)
|
(ex/raise :type :assertion
|
||||||
(cts/shape? shape-new))))))]
|
:code :data-validation
|
||||||
|
:hint "invalid shape found after applying changes")))))]
|
||||||
|
|
||||||
(->> (into #{} (map :page-id) items)
|
(->> (into #{} (map :page-id) items)
|
||||||
(mapcat (fn [page-id]
|
(mapcat (fn [page-id]
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#?(:cljs (:require-macros [app.common.schema :refer [ignoring]]))
|
#?(:cljs (:require-macros [app.common.schema :refer [ignoring]]))
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
|
||||||
[app.common.pprint :as pp]
|
[app.common.pprint :as pp]
|
||||||
[app.common.schema.generators :as sg]
|
[app.common.schema.generators :as sg]
|
||||||
[app.common.schema.openapi :as-alias oapi]
|
[app.common.schema.openapi :as-alias oapi]
|
||||||
|
@ -243,59 +242,35 @@
|
||||||
(defn- fast-check!
|
(defn- fast-check!
|
||||||
"A fast path for checking process, assumes the ILazySchema protocol
|
"A fast path for checking process, assumes the ILazySchema protocol
|
||||||
implemented on the provided `s` schema. Sould not be used directly."
|
implemented on the provided `s` schema. Sould not be used directly."
|
||||||
[s value]
|
[s type code hint value]
|
||||||
(when-not ^boolean (-validate s value)
|
(when-not ^boolean (-validate s value)
|
||||||
(let [hint (d/nilv dm/*assert-context* "check error")
|
(let [explain (-explain s value)]
|
||||||
explain (-explain s value)]
|
(throw (ex-info hint {:type type
|
||||||
(throw (ex-info hint {:type :assertion
|
:code code
|
||||||
:code :data-validation
|
|
||||||
:hint hint
|
:hint hint
|
||||||
::explain explain}))))
|
::explain explain}))))
|
||||||
true)
|
value)
|
||||||
|
|
||||||
(declare ^:private lazy-schema)
|
(declare ^:private lazy-schema)
|
||||||
|
|
||||||
(defn check-fn
|
(defn check-fn
|
||||||
"Create a predefined check function"
|
"Create a predefined check function"
|
||||||
[s]
|
[s & {:keys [hint type code]}]
|
||||||
(let [schema (if (lazy-schema? s) s (lazy-schema s))]
|
(let [schema (if (lazy-schema? s) s (lazy-schema s))
|
||||||
(partial fast-check! schema)))
|
hint (or ^boolean hint "check error")
|
||||||
|
type (or ^boolean type :assertion)
|
||||||
|
code (or ^boolean code :data-validation)]
|
||||||
|
(partial fast-check! schema type code hint)))
|
||||||
|
|
||||||
(defn check!
|
(defn check!
|
||||||
"A helper intended to be used on assertions for validate/check the
|
"A helper intended to be used on assertions for validate/check the
|
||||||
schema over provided data. Raises an assertion exception, should be
|
schema over provided data. Raises an assertion exception."
|
||||||
used together with `dm/assert!` or `dm/verify!`."
|
[s value & {:keys [hint type code]}]
|
||||||
[s value]
|
(let [s (if (lazy-schema? s) s (lazy-schema s))
|
||||||
(let [s (if (lazy-schema? s) s (lazy-schema s))]
|
hint (or ^boolean hint "check error")
|
||||||
(fast-check! s value)))
|
type (or ^boolean type :assertion)
|
||||||
|
code (or ^boolean code :data-validation)]
|
||||||
(defn- fast-validate!
|
(fast-check! s type code hint value)))
|
||||||
"A fast path for validation process, assumes the ILazySchema protocol
|
|
||||||
implemented on the provided `s` schema. Sould not be used directly."
|
|
||||||
([s value] (fast-validate! s value nil))
|
|
||||||
([s value options]
|
|
||||||
(when-not ^boolean (-validate s value)
|
|
||||||
(let [explain (-explain s value)
|
|
||||||
options (into {:type :validation
|
|
||||||
:code :data-validation
|
|
||||||
::explain explain}
|
|
||||||
options)
|
|
||||||
hint (get options :hint "schema validation error")]
|
|
||||||
(throw (ex-info hint options))))
|
|
||||||
value))
|
|
||||||
|
|
||||||
(defn validate-fn
|
|
||||||
"Create a predefined validate function that raises an expception"
|
|
||||||
[s]
|
|
||||||
(let [schema (if (lazy-schema? s) s (lazy-schema s))]
|
|
||||||
(partial fast-validate! schema)))
|
|
||||||
|
|
||||||
(defn validate!
|
|
||||||
"A generic validation function for predefined schemas."
|
|
||||||
([s value] (validate! s value nil))
|
|
||||||
([s value options]
|
|
||||||
(let [s (if (lazy-schema? s) s (lazy-schema s))]
|
|
||||||
(fast-validate! s value options))))
|
|
||||||
|
|
||||||
(defn register! [type s]
|
(defn register! [type s]
|
||||||
(let [s (if (map? s) (m/-simple-schema s) s)]
|
(let [s (if (map? s) (m/-simple-schema s) s)]
|
||||||
|
@ -1005,6 +980,12 @@
|
||||||
(def check-email!
|
(def check-email!
|
||||||
(check-fn ::email))
|
(check-fn ::email))
|
||||||
|
|
||||||
|
(def check-uuid!
|
||||||
|
(check-fn ::uuid :hint "expected valid uuid instance"))
|
||||||
|
|
||||||
|
(def check-string!
|
||||||
|
(check-fn :string :hint "expected string"))
|
||||||
|
|
||||||
(def check-coll-of-uuid!
|
(def check-coll-of-uuid!
|
||||||
(check-fn ::coll-of-uuid))
|
(check-fn ::coll-of-uuid))
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
[app.common.colors :as clr]
|
[app.common.colors :as clr]
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.exceptions :as ex]
|
||||||
[app.common.files.helpers :as cfh]
|
[app.common.files.helpers :as cfh]
|
||||||
[app.common.geom.matrix :as gmt]
|
[app.common.geom.matrix :as gmt]
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
|
@ -29,12 +30,12 @@
|
||||||
{:x 0 :y 0 :width 1 :height 1})
|
{:x 0 :y 0 :width 1 :height 1})
|
||||||
|
|
||||||
(defn- assert-valid-num [attr num]
|
(defn- assert-valid-num [attr num]
|
||||||
(dm/verify!
|
(when-not (and (d/num? num)
|
||||||
["%1 attribute has invalid value: %2" (d/name attr) num]
|
(<= num max-safe-int)
|
||||||
(and (d/num? num)
|
(>= num min-safe-int))
|
||||||
(<= num max-safe-int)
|
(ex/raise :type :assertion
|
||||||
(>= num min-safe-int)))
|
:code :data-validation
|
||||||
|
:hint (str "invalid numeric value for `" attr "`: " num)))
|
||||||
(cond
|
(cond
|
||||||
(and (> num 0) (< num 1)) 1
|
(and (> num 0) (< num 1)) 1
|
||||||
(and (< num 0) (> num -1)) -1
|
(and (< num 0) (> num -1)) -1
|
||||||
|
@ -43,19 +44,21 @@
|
||||||
(defn- assert-valid-pos-num
|
(defn- assert-valid-pos-num
|
||||||
[attr num]
|
[attr num]
|
||||||
|
|
||||||
(dm/verify!
|
(when-not (pos? num)
|
||||||
["%1 attribute should be positive" (d/name attr)]
|
(ex/raise :type :assertion
|
||||||
(pos? num))
|
:code :data-validation
|
||||||
|
:hint (str "invalid numeric value for `" attr "`: " num " (should be positive)")))
|
||||||
num)
|
num)
|
||||||
|
|
||||||
(defn- assert-valid-blend-mode
|
(defn- assert-valid-blend-mode
|
||||||
[mode]
|
[mode]
|
||||||
(let [clean-value (-> mode str/trim str/lower keyword)]
|
(let [value (-> mode str/trim str/lower keyword)]
|
||||||
(dm/verify!
|
|
||||||
["%1 is not a valid blend mode" clean-value]
|
(when-not (contains? cts/blend-modes value)
|
||||||
(contains? cts/blend-modes clean-value))
|
(ex/raise :type :assertion
|
||||||
clean-value))
|
:code :data-validation
|
||||||
|
:hint (str "unexpected blend mode: " value)))
|
||||||
|
value))
|
||||||
|
|
||||||
(defn- svg-dimensions
|
(defn- svg-dimensions
|
||||||
[{:keys [attrs] :as data}]
|
[{:keys [attrs] :as data}]
|
||||||
|
|
|
@ -116,7 +116,7 @@
|
||||||
(sm/register! ::color-attrs schema:color-attrs)
|
(sm/register! ::color-attrs schema:color-attrs)
|
||||||
|
|
||||||
(def check-color!
|
(def check-color!
|
||||||
(sm/check-fn schema:color))
|
(sm/check-fn schema:color :hint "expected valid color struct"))
|
||||||
|
|
||||||
(def check-recent-color!
|
(def check-recent-color!
|
||||||
(sm/check-fn schema:recent-color))
|
(sm/check-fn schema:recent-color))
|
||||||
|
|
|
@ -355,7 +355,8 @@
|
||||||
(sm/check-fn schema:shape-attrs))
|
(sm/check-fn schema:shape-attrs))
|
||||||
|
|
||||||
(def check-shape!
|
(def check-shape!
|
||||||
(sm/check-fn schema:shape))
|
(sm/check-fn schema:shape
|
||||||
|
:hint "expected valid shape"))
|
||||||
|
|
||||||
(def valid-shape?
|
(def valid-shape?
|
||||||
(sm/lazy-validator schema:shape))
|
(sm/lazy-validator schema:shape))
|
||||||
|
|
|
@ -1725,8 +1725,8 @@
|
||||||
[:images [:set :map]]
|
[:images [:set :map]]
|
||||||
[:position {:optional true} ::gpt/point]])
|
[:position {:optional true} ::gpt/point]])
|
||||||
|
|
||||||
(def validate-paste-data!
|
(def paste-data-valid?
|
||||||
(sm/validate-fn schema:paste-data))
|
(sm/lazy-validator schema:paste-data))
|
||||||
|
|
||||||
(defn- paste-transit
|
(defn- paste-transit
|
||||||
[{:keys [images] :as pdata}]
|
[{:keys [images] :as pdata}]
|
||||||
|
@ -1751,8 +1751,10 @@
|
||||||
(let [file-id (:current-file-id state)
|
(let [file-id (:current-file-id state)
|
||||||
features (features/get-team-enabled-features state)]
|
features (features/get-team-enabled-features state)]
|
||||||
|
|
||||||
(validate-paste-data! pdata {:hint "invalid paste data"
|
(when-not (paste-data-valid? pdata)
|
||||||
:code :invalid-paste-data})
|
(ex/raise :type :validation
|
||||||
|
:code :invalid-paste-data
|
||||||
|
:hibt "invalid paste data found"))
|
||||||
|
|
||||||
(cfeat/check-paste-features! features (:features pdata))
|
(cfeat/check-paste-features! features (:features pdata))
|
||||||
(if (= file-id (:file-id pdata))
|
(if (= file-id (:file-id pdata))
|
||||||
|
|
|
@ -465,16 +465,16 @@
|
||||||
(defn change-color-in-selected
|
(defn change-color-in-selected
|
||||||
[operations new-color old-color]
|
[operations new-color old-color]
|
||||||
|
|
||||||
(dm/verify!
|
(dm/assert!
|
||||||
"expected valid change color operations"
|
"expected valid color operations"
|
||||||
(check-change-color-operations! operations))
|
(check-change-color-operations! operations))
|
||||||
|
|
||||||
(dm/verify!
|
(dm/assert!
|
||||||
"expected a valid color struct for new-color param"
|
"expected valid color structure"
|
||||||
(ctc/check-color! new-color))
|
(ctc/check-color! new-color))
|
||||||
|
|
||||||
(dm/verify!
|
(dm/assert!
|
||||||
"expected a valid color struct for old-color param"
|
"expected valid color structure"
|
||||||
(ctc/check-color! old-color))
|
(ctc/check-color! old-color))
|
||||||
|
|
||||||
(ptk/reify ::change-color-in-selected
|
(ptk/reify ::change-color-in-selected
|
||||||
|
@ -498,7 +498,7 @@
|
||||||
[color stroke?]
|
[color stroke?]
|
||||||
|
|
||||||
(dm/assert!
|
(dm/assert!
|
||||||
"should be a valid color"
|
"expected valid color structure"
|
||||||
(ctc/check-color! color))
|
(ctc/check-color! color))
|
||||||
|
|
||||||
(ptk/reify ::apply-color-from-palette
|
(ptk/reify ::apply-color-from-palette
|
||||||
|
|
|
@ -193,9 +193,17 @@
|
||||||
|
|
||||||
(defn rename-color
|
(defn rename-color
|
||||||
[file-id id new-name]
|
[file-id id new-name]
|
||||||
(dm/verify! (uuid? file-id))
|
(dm/assert!
|
||||||
(dm/verify! (uuid? id))
|
"expected valid uuid for `id`"
|
||||||
(dm/verify! (string? new-name))
|
(uuid? id))
|
||||||
|
|
||||||
|
(dm/assert!
|
||||||
|
"expected valid uuid for `file-id`"
|
||||||
|
(uuid? file-id))
|
||||||
|
|
||||||
|
(dm/assert!
|
||||||
|
"expected valid string for `new-name`"
|
||||||
|
(string? new-name))
|
||||||
|
|
||||||
(ptk/reify ::rename-color
|
(ptk/reify ::rename-color
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
|
@ -243,8 +251,15 @@
|
||||||
|
|
||||||
(defn rename-media
|
(defn rename-media
|
||||||
[id new-name]
|
[id new-name]
|
||||||
(dm/verify! (uuid? id))
|
|
||||||
(dm/verify! (string? new-name))
|
(dm/assert!
|
||||||
|
"expected valid uuid for `id`"
|
||||||
|
(uuid? id))
|
||||||
|
|
||||||
|
(dm/assert!
|
||||||
|
"expected valid string for `new-name`"
|
||||||
|
(string? new-name))
|
||||||
|
|
||||||
(ptk/reify ::rename-media
|
(ptk/reify ::rename-media
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
|
@ -261,8 +276,11 @@
|
||||||
(rx/of (dch/commit-changes changes))))))))
|
(rx/of (dch/commit-changes changes))))))))
|
||||||
|
|
||||||
(defn delete-media
|
(defn delete-media
|
||||||
[{:keys [id] :as params}]
|
[{:keys [id]}]
|
||||||
(dm/assert! (uuid? id))
|
(dm/assert!
|
||||||
|
"expected valid uuid for `id`"
|
||||||
|
(uuid? id))
|
||||||
|
|
||||||
(ptk/reify ::delete-media
|
(ptk/reify ::delete-media
|
||||||
ev/Event
|
ev/Event
|
||||||
(-data [_] {:id id})
|
(-data [_] {:id id})
|
||||||
|
@ -435,8 +453,14 @@
|
||||||
(defn rename-component
|
(defn rename-component
|
||||||
"Rename the component with the given id, in the current file library."
|
"Rename the component with the given id, in the current file library."
|
||||||
[id new-name]
|
[id new-name]
|
||||||
(dm/verify! (uuid? id))
|
(dm/assert!
|
||||||
(dm/verify! (string? new-name))
|
"expected an uuid instance"
|
||||||
|
(uuid? id))
|
||||||
|
|
||||||
|
(dm/assert!
|
||||||
|
"expected string for new-name"
|
||||||
|
(string? new-name))
|
||||||
|
|
||||||
(ptk/reify ::rename-component
|
(ptk/reify ::rename-component
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
|
@ -487,8 +511,11 @@
|
||||||
|
|
||||||
(defn delete-component
|
(defn delete-component
|
||||||
"Delete the component with the given id, from the current file library."
|
"Delete the component with the given id, from the current file library."
|
||||||
[{:keys [id] :as params}]
|
[{:keys [id]}]
|
||||||
(dm/assert! (uuid? id))
|
(dm/assert!
|
||||||
|
"expected valid uuid for `id`"
|
||||||
|
(uuid? id))
|
||||||
|
|
||||||
(ptk/reify ::delete-component
|
(ptk/reify ::delete-component
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
|
@ -1129,7 +1156,9 @@
|
||||||
(defn touch-component
|
(defn touch-component
|
||||||
"Update the modified-at attribute of the component to now"
|
"Update the modified-at attribute of the component to now"
|
||||||
[id]
|
[id]
|
||||||
(dm/verify! (uuid? id))
|
(dm/assert!
|
||||||
|
"expected valid uuid for `id`"
|
||||||
|
(uuid? id))
|
||||||
(ptk/reify ::touch-component
|
(ptk/reify ::touch-component
|
||||||
cljs.core/IDeref
|
cljs.core/IDeref
|
||||||
(-deref [_] [id])
|
(-deref [_] [id])
|
||||||
|
|
|
@ -98,8 +98,8 @@
|
||||||
(add-shape shape {}))
|
(add-shape shape {}))
|
||||||
([shape {:keys [no-select? no-update-layout?]}]
|
([shape {:keys [no-select? no-update-layout?]}]
|
||||||
|
|
||||||
(dm/verify!
|
(dm/assert!
|
||||||
"expected a valid shape"
|
"expected valid shape"
|
||||||
(cts/check-shape! shape))
|
(cts/check-shape! shape))
|
||||||
|
|
||||||
(ptk/reify ::add-shape
|
(ptk/reify ::add-shape
|
||||||
|
|
Loading…
Add table
Reference in a new issue