diff --git a/backend/src/uxbox/util/exceptions.clj b/backend/src/uxbox/util/exceptions.clj index b39a9e8ce..f5bdde57b 100644 --- a/backend/src/uxbox/util/exceptions.clj +++ b/backend/src/uxbox/util/exceptions.clj @@ -4,6 +4,8 @@ ;; ;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz> +;; WARNING: DEPRECATED: please use uxbox.common.exceptions + (ns uxbox.util.exceptions "A helpers for work with exceptions." (:require [clojure.spec.alpha :as s])) diff --git a/backend/src/uxbox/util/spec.clj b/backend/src/uxbox/util/spec.clj index efd8561d9..1fac49aaf 100644 --- a/backend/src/uxbox/util/spec.clj +++ b/backend/src/uxbox/util/spec.clj @@ -4,6 +4,8 @@ ;; ;; Copyright (c) 2016-2019 Andrey Antukh <niwi@niwi.nz> +;; WARNING: DEPRECATED: please use uxbox.common.spec + (ns uxbox.util.spec (:refer-clojure :exclude [keyword uuid vector boolean map set]) (:require diff --git a/common/uxbox/common/exceptions.cljc b/common/uxbox/common/exceptions.cljc new file mode 100644 index 000000000..1b271c36e --- /dev/null +++ b/common/uxbox/common/exceptions.cljc @@ -0,0 +1,33 @@ +;; 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) 2016 Andrey Antukh <niwi@niwi.nz> + +(ns uxbox.common.exceptions + "A helpers for work with exceptions." + (:require [clojure.spec.alpha :as s])) + +(s/def ::type keyword?) +(s/def ::code keyword?) +(s/def ::mesage string?) +(s/def ::hint string?) +(s/def ::cause #?(:clj #(instance? Throwable %) + :cljs #(instance? js/Error %))) +(s/def ::error-params + (s/keys :req-un [::type] + :opt-un [::code + ::hint + ::mesage + ::cause])) + +(defn error + [& {:keys [type code message hint cause] :as params}] + (s/assert ::error-params params) + (let [message (or message hint "") + payload (dissoc params :cause :message)] + (ex-info message payload cause))) + +(defmacro raise + [& args] + `(throw (error ~@args))) diff --git a/common/uxbox/common/pages.cljc b/common/uxbox/common/pages.cljc index a93ce7942..6be202fe9 100644 --- a/common/uxbox/common/pages.cljc +++ b/common/uxbox/common/pages.cljc @@ -1,6 +1,7 @@ (ns uxbox.common.pages "A common (clj/cljs) functions and specs for pages." (:require + [uxbox.common.spec :as us] [clojure.spec.alpha :as s] [uxbox.common.data :as d])) @@ -136,10 +137,6 @@ ;; --- Changes Processing Impl -(defn change - [data] - (s/assert ::change data)) - (declare process-change) (declare process-mod-shape) (declare process-mod-opts) @@ -151,7 +148,7 @@ (defn process-changes [data items] - (->> (s/assert ::changes items) + (->> (us/assert ::changes items) (reduce process-change data))) (defn- process-change diff --git a/common/uxbox/common/spec.cljc b/common/uxbox/common/spec.cljc new file mode 100644 index 000000000..f3319f733 --- /dev/null +++ b/common/uxbox/common/spec.cljc @@ -0,0 +1,133 @@ +;; 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) 2016-2019 Andrey Antukh <niwi@niwi.nz> + +(ns uxbox.common.spec + "Data manipulation and query helper functions." + (:refer-clojure :exclude [assert]) + #?(:cljs (:require-macros [uxbox.common.spec :refer [assert]])) + (:require + #?(:clj [datoteka.core :as fs]) + #?(:clj [clojure.spec.alpha :as s] + :cljs [cljs.spec.alpha :as s]) + [expound.alpha :as expound] + [uxbox.common.exceptions :as ex] + [cuerdas.core :as str])) + +(s/check-asserts true) + +;; --- Constants + +(def email-rx + #"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$") + +(def uuid-rx + #"^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$") + +;; --- Conformers + +(defn- uuid-conformer + [v] + (if (uuid? v) + v + (if (string? v) + (if (re-matches uuid-rx v) + #?(:cljs (uuid v) + :clj (java.util.UUID/fromString v)) + + (if (str/empty? v) nil ::s/invalid)) + ::s/invalid))) + +(defn boolean-conformer + [v] + (if (boolean? v) + v + (if (string? v) + (if (re-matches #"^(?:t|true|false|f|0|1)$" v) + (contains? #{"t" "true" "1"} v) + ::s/invalid) + ::s/invalid))) + +(defn boolean-unformer + [v] + (if v "true" "false")) + +(defn- number-conformer + [v] + (cond + (number? v) v + (str/numeric? v) + #?(:clj (Double/parseDouble v) + :cljs (js/parseFloat v)) + :else ::s/invalid)) + +(defn- integer-conformer + [v] + (cond + (integer? v) v + (string? v) + (if (re-matches #"^[-+]?\d+$" v) + #?(:clj (Long/parseLong v) + :cljs (js/parseInt v 10)) + ::s/invalid) + :else ::s/invalid)) + +(defn- color-conformer + [v] + (if (and (string? v) (re-matches #"^#[0-9A-Fa-f]{6}$" v)) + v + ::s/invalid)) + +(defn- email-conformer + [v] + (if (and (string? v) (re-matches email-rx v)) + v + ::s/invalid)) + +#?(:clj + (defn path-conformer + [v] + (cond + (string? v) (fs/path v) + (fs/path? v) v + :else ::s/invalid))) + + +;; --- Default Specs + +(s/def ::inst inst?) +(s/def ::email (s/conformer email-conformer str)) +(s/def ::color (s/conformer color-conformer str)) +(s/def ::uuid (s/conformer uuid-conformer str)) +(s/def ::boolean (s/conformer boolean-conformer boolean-unformer)) +(s/def ::number (s/conformer number-conformer str)) +(s/def ::integer (s/conformer integer-conformer str)) +(s/def ::not-empty-string (s/and string? #(not (str/empty? %)))) +#?(:clj (s/def ::path (s/conformer path-conformer str))) + +;; --- Macros + +(defn assert* + [spec x] + (s/assert* spec x)) + +#?(:clj + (defmacro assert + "Always active assertion macro (does not obey to :elide-asserts)" + [spec x] + `(assert* ~spec ~x))) + +;; --- Public Api + +(defn conform + [spec data] + (let [result (s/conform spec data)] + (when (= result ::s/invalid) + (throw (ex/error :type :validation + :code :spec-validation + :explain (with-out-str + (expound/printer data)) + :data (::s/problems data)))) + result)) diff --git a/frontend/src/uxbox/main.cljs b/frontend/src/uxbox/main.cljs index 2902cfe37..f792c0194 100644 --- a/frontend/src/uxbox/main.cljs +++ b/frontend/src/uxbox/main.cljs @@ -27,8 +27,6 @@ ;; --- i18n (declare reinit) -(s/check-asserts true) - (rx/sub! i18n/locale-sub #(reinit)) ;; --- Error Handling diff --git a/frontend/src/uxbox/main/data/auth.cljs b/frontend/src/uxbox/main/data/auth.cljs index 8506e9b14..bdac80ea1 100644 --- a/frontend/src/uxbox/main/data/auth.cljs +++ b/frontend/src/uxbox/main/data/auth.cljs @@ -9,12 +9,12 @@ [cljs.spec.alpha :as s] [beicon.core :as rx] [potok.core :as ptk] + [uxbox.common.spec :as us] [uxbox.main.repo :as rp] [uxbox.main.store :refer [initial-state]] [uxbox.main.data.users :as du] [uxbox.util.messages :as um] [uxbox.util.router :as rt] - [uxbox.util.spec :as us] [uxbox.util.i18n :as i18n :refer [tr]] [uxbox.util.storage :refer [storage]])) @@ -45,7 +45,7 @@ (defn login [{:keys [username password] :as data}] - (s/assert ::login-params data) + (us/assert ::login-params data) (ptk/reify ::login ptk/UpdateEvent (update [_ state] @@ -98,8 +98,8 @@ (defn register "Create a register event instance." [data on-error] - (s/assert ::register-params data) - (s/assert ::us/fn on-error) + (us/assert ::register-params data) + (us/assert fn? on-error) (ptk/reify ::register ptk/WatchEvent (watch [_ state stream] @@ -123,7 +123,7 @@ (defn recovery-request [data] - (s/assert ::recovery-request-params data) + (us/assert ::recovery-request-params data) (ptk/reify ::recover-request ptk/WatchEvent (watch [_ state stream] @@ -166,7 +166,7 @@ (defn recovery [{:keys [token password] :as data}] - (s/assert ::recovery-params data) + (us/assert ::recovery-params data) (ptk/reify ::recovery ptk/WatchEvent (watch [_ state stream] diff --git a/frontend/src/uxbox/main/data/history.cljs b/frontend/src/uxbox/main/data/history.cljs index 011b3570a..891e046b8 100644 --- a/frontend/src/uxbox/main/data/history.cljs +++ b/frontend/src/uxbox/main/data/history.cljs @@ -9,21 +9,21 @@ [beicon.core :as rx] [cljs.spec.alpha :as s] [potok.core :as ptk] + [uxbox.common.spec :as us] [uxbox.main.data.projects :as dp] [uxbox.main.repo :as rp] - [uxbox.util.data :refer [replace-by-id index-by]] - [uxbox.util.spec :as us])) + [uxbox.util.data :refer [replace-by-id index-by]])) ;; --- Schema -(s/def ::pinned ::us/bool) -(s/def ::id ::us/uuid) -(s/def ::label ::us/string) -(s/def ::project ::us/uuid) -(s/def ::created-at ::us/inst) -(s/def ::modified-at ::us/inst) -(s/def ::version ::us/number) -(s/def ::user ::us/uuid) +(s/def ::pinned boolean?) +(s/def ::id uuid?) +(s/def ::label string?) +(s/def ::project uuid?) +(s/def ::created-at inst?) +(s/def ::modified-at inst?) +(s/def ::version number?) +(s/def ::user uuid?) (s/def ::shapes (s/every ::dp/minimal-shape :kind vector?)) @@ -52,7 +52,7 @@ (defn initialize [id] - (s/assert ::us/uuid id) + (us/assert ::us/uuid id) (ptk/reify ::initialize ptk/UpdateEvent (update [_ state] @@ -71,7 +71,7 @@ (defn watch-page-changes [id] - (s/assert ::us/uuid id) + (us/assert ::us/uuid id) (reify ptk/WatchEvent (watch [_ state stream] @@ -87,7 +87,7 @@ (defn pinned-history-fetched [items] - (s/assert ::history-entries items) + (us/assert ::history-entries items) (ptk/reify ::pinned-history-fetched ptk/UpdateEvent (update [_ state] @@ -104,7 +104,7 @@ (defn fetch-pinned-history [id] - (s/assert ::us/uuid id) + (us/assert ::us/uuid id) (ptk/reify ::fetch-pinned-history ptk/WatchEvent (watch [_ state s] @@ -117,7 +117,7 @@ (defn history-fetched [items] - (s/assert ::history-entries items) + (us/assert ::history-entries items) (ptk/reify ::history-fetched ptk/UpdateEvent (update [_ state] @@ -140,7 +140,7 @@ ([id] (fetch-history id nil)) ([id {:keys [since max]}] - (s/assert ::us/uuid id) + (us/assert ::us/uuid id) (ptk/reify ::fetch-history ptk/WatchEvent (watch [_ state s] @@ -182,7 +182,7 @@ (defn select [version] - (s/assert int? version) + (us/assert int? version) (ptk/reify ::select ptk/UpdateEvent (update [_ state] @@ -238,7 +238,7 @@ (defn history-updated [item] - (s/assert ::history-entry item) + (us/assert ::history-entry item) (ptk/reify ::history-item-updated ptk/UpdateEvent (update [_ state] diff --git a/frontend/src/uxbox/main/data/images.cljs b/frontend/src/uxbox/main/data/images.cljs index 51802dc1d..b635987d4 100644 --- a/frontend/src/uxbox/main/data/images.cljs +++ b/frontend/src/uxbox/main/data/images.cljs @@ -10,6 +10,7 @@ [cuerdas.core :as str] [beicon.core :as rx] [potok.core :as ptk] + [uxbox.common.spec :as us] [uxbox.main.store :as st] [uxbox.main.repo.core :as rp] [uxbox.util.i18n :refer [tr]] @@ -17,7 +18,6 @@ [uxbox.util.data :refer (jscoll->vec)] [uxbox.util.uuid :as uuid] [uxbox.util.time :as ts] - [uxbox.util.spec :as us] [uxbox.util.router :as r] [uxbox.util.files :as files])) @@ -29,11 +29,11 @@ (s/def ::modified-at inst?) (s/def ::created-at inst?) (s/def ::mimetype string?) -(s/def ::thumbnail us/url-str?) +(s/def ::thumbnail string?) (s/def ::id uuid?) -(s/def ::url us/url-str?) -(s/def ::collection-id (s/nilable ::us/uuid)) -(s/def ::user-id ::us/uuid) +(s/def ::url string?) +(s/def ::collection-id (s/nilable uuid?)) +(s/def ::user-id uuid?) (s/def ::collection-entity (s/keys :req-un [::id @@ -59,7 +59,7 @@ (defn collections-fetched [items] - (s/assert (s/every ::collection-entity) items) + (us/assert (s/every ::collection-entity) items) (ptk/reify ::collections-fetched ptk/UpdateEvent (update [_ state] @@ -83,7 +83,7 @@ (defn collection-created [item] - (s/assert ::collection-entity item) + (us/assert ::collection-entity item) (ptk/reify ::collection-created ptk/UpdateEvent (update [_ state] @@ -109,7 +109,7 @@ (defn collection-updated [item] - {:pre [(us/valid? ::collection-entity item)]} + (us/assert ::collection-entity item) (CollectionUpdated. item)) ;; --- Update Collection @@ -161,7 +161,7 @@ (defn image-created [item] - (s/assert ::image-entity item) + (us/assert ::image-entity item) (ptk/reify ::image-created ptk/UpdateEvent (update [_ state] @@ -174,8 +174,8 @@ (defn create-images ([id files] (create-images id files identity)) ([id files on-uploaded] - (s/assert (s/nilable ::us/uuid) id) - (s/assert fn? on-uploaded) + (us/assert (s/nilable ::us/uuid) id) + (us/assert fn? on-uploaded) (ptk/reify ::create-images ptk/UpdateEvent (update [_ state] @@ -225,7 +225,7 @@ (defn images-fetched [items] - (s/assert (s/every ::image-entity) items) + (us/assert (s/every ::image-entity) items) (ptk/reify ::images-fetched ptk/UpdateEvent (update [_ state] @@ -239,7 +239,7 @@ (defn fetch-images "Fetch a list of images of the selected collection" [id] - (s/assert (s/nilable ::us/uuid) id) + (us/assert (s/nilable ::us/uuid) id) (ptk/reify ::fetch-images ptk/WatchEvent (watch [_ state s] diff --git a/frontend/src/uxbox/main/data/projects.cljs b/frontend/src/uxbox/main/data/projects.cljs index 9f95c455a..b519d4c7d 100644 --- a/frontend/src/uxbox/main/data/projects.cljs +++ b/frontend/src/uxbox/main/data/projects.cljs @@ -11,9 +11,9 @@ [cuerdas.core :as str] [potok.core :as ptk] [uxbox.common.pages :as cp] + [uxbox.common.spec :as us] [uxbox.main.repo.core :as rp] [uxbox.util.router :as rt] - [uxbox.util.spec :as us] [uxbox.util.time :as dt] [uxbox.util.timers :as ts] [uxbox.util.uuid :as uuid])) @@ -21,9 +21,9 @@ ;; --- Specs (s/def ::id ::us/uuid) -(s/def ::name ::us/string) +(s/def ::name string?) (s/def ::user ::us/uuid) -(s/def ::type ::us/keyword) +(s/def ::type keyword?) (s/def ::file-id ::us/uuid) (s/def ::project-id ::us/uuid) (s/def ::created-at ::us/inst) @@ -134,7 +134,7 @@ (defn projects-fetched [projects] - (s/assert (s/every ::project) projects) + (us/assert (s/every ::project) projects) (ptk/reify ::projects-fetched ptk/UpdateEvent (update [_ state] @@ -158,7 +158,7 @@ (defn fetch-file [id] - (s/assert ::us/uuid id) + (us/assert ::us/uuid id) (ptk/reify ::fetch-file ptk/WatchEvent (watch [_ state stream] @@ -169,7 +169,7 @@ (defn files-fetched [files] - (s/assert (s/every ::file) files) + (us/assert (s/every ::file) files) (ptk/reify ::files-fetched cljs.core/IDeref (-deref [_] files) @@ -227,7 +227,7 @@ (defn delete-project [id] - (s/assert ::us/uuid id) + (us/assert ::us/uuid id) (ptk/reify ::delete-project ptk/UpdateEvent (update [_ state] @@ -242,7 +242,7 @@ (defn delete-file [id] - (s/assert ::us/uuid id) + (us/assert ::us/uuid id) (ptk/reify ::delete-file ptk/UpdateEvent (update [_ state] @@ -273,7 +273,7 @@ (defn go-to [file-id] - (s/assert ::us/uuid file-id) + (us/assert ::us/uuid file-id) (ptk/reify ::go-to ptk/WatchEvent (watch [_ state stream] @@ -284,7 +284,7 @@ (defn go-to-project [id] - (s/assert (s/nilable ::us/uuid) id) + (us/assert (s/nilable ::us/uuid) id) (ptk/reify ::go-to-project ptk/WatchEvent (watch [_ state stream] @@ -299,7 +299,7 @@ (defn fetch-pages [file-id] - (s/assert ::us/uuid file-id) + (us/assert ::us/uuid file-id) (reify ptk/WatchEvent (watch [_ state s] @@ -310,7 +310,7 @@ (defn pages-fetched [pages] - (s/assert (s/every ::page) pages) + (us/assert (s/every ::page) pages) (ptk/reify ::pages-fetched IDeref (-deref [_] pages) @@ -326,7 +326,7 @@ (defn fetch-page "Fetch page by id." [id] - (s/assert ::us/uuid id) + (us/assert ::us/uuid id) (reify ptk/WatchEvent (watch [_ state s] @@ -337,7 +337,7 @@ (defn page-fetched [data] - (s/assert ::page data) + (us/assert ::page data) (ptk/reify ::page-fetched IDeref (-deref [_] data) @@ -377,7 +377,7 @@ (defn page-created [{:keys [id file-id] :as page}] - (s/assert ::page page) + (us/assert ::page page) (ptk/reify ::page-created cljs.core/IDeref (-deref [_] page) @@ -393,7 +393,7 @@ ptk/WatchEvent (watch [_ state stream] - (rx/of (uxbox.main.data.projects/fetch-file file-id))))) + (rx/of (fetch-file file-id))))) ;; --- Rename Page @@ -402,8 +402,8 @@ (defn rename-page [id name] - (s/assert ::us/uuid id) - (s/assert string? name) + (us/assert ::us/uuid id) + (us/assert string? name) (ptk/reify ::rename-page ptk/UpdateEvent (update [_ state] @@ -461,7 +461,7 @@ (defn page-persisted [{:keys [id] :as page}] - (s/assert ::page page) + (us/assert ::page page) (ptk/reify ::page-persisted cljs.core/IDeref (-deref [_] page) diff --git a/frontend/src/uxbox/main/data/undo.cljs b/frontend/src/uxbox/main/data/undo.cljs index 34b56e4fe..b0cfebc99 100644 --- a/frontend/src/uxbox/main/data/undo.cljs +++ b/frontend/src/uxbox/main/data/undo.cljs @@ -9,9 +9,9 @@ [beicon.core :as rx] [cljs.spec.alpha :as s] [potok.core :as ptk] + [uxbox.common.spec :as us] [uxbox.main.data.projects :as dp] - [uxbox.main.store :as st] - [uxbox.util.spec :as us])) + [uxbox.main.store :as st])) (def MAX-STACK-SIZE 50) @@ -24,7 +24,7 @@ (defn watch-page-changes [id] - (s/assert ::us/uuid id) + (us/assert ::us/uuid id) (ptk/reify ::watch-page-changes ptk/WatchEvent (watch [_ state stream] @@ -40,7 +40,7 @@ (defn save-undo-entry [id] - (s/assert ::us/uuid id) + (us/assert ::us/uuid id) (letfn [(cons-entry [stack entry] (let [stack (cons entry stack)] (if (> (count stack) MAX-STACK-SIZE) diff --git a/frontend/src/uxbox/main/data/users.cljs b/frontend/src/uxbox/main/data/users.cljs index 3785731d0..4aa2fcc0d 100644 --- a/frontend/src/uxbox/main/data/users.cljs +++ b/frontend/src/uxbox/main/data/users.cljs @@ -6,14 +6,14 @@ (ns uxbox.main.data.users (:require - [cljs.spec.alpha :as s] [beicon.core :as rx] + [cljs.spec.alpha :as s] [cuerdas.core :as str] [potok.core :as ptk] + [uxbox.common.spec :as us] [uxbox.main.repo.core :as rp] [uxbox.util.i18n :as i18n :refer [tr]] [uxbox.util.messages :as uum] - [uxbox.util.spec :as us] [uxbox.util.storage :refer [storage]])) ;; --- Common Specs @@ -42,7 +42,7 @@ (defn profile-fetched [data] - (s/assert ::profile-fetched data) + (us/assert ::profile-fetched data) (ptk/reify ::profile-fetched ptk/UpdateEvent (update [_ state] @@ -73,9 +73,9 @@ (defn form->update-profile [data on-success on-error] - (s/assert ::update-profile-params data) - (s/assert ::us/fn on-error) - (s/assert ::us/fn on-success) + (us/assert ::update-profile-params data) + (us/assert fn? on-error) + (us/assert fn? on-success) (reify ptk/WatchEvent (watch [_ state s] @@ -102,9 +102,9 @@ (defn update-password [data {:keys [on-success on-error]}] - (s/assert ::update-password-params data) - (s/assert ::us/fn on-success) - (s/assert ::us/fn on-error) + (us/assert ::update-password-params data) + (us/assert fn? on-success) + (us/assert fn? on-error) (reify ptk/WatchEvent (watch [_ state s] @@ -127,9 +127,11 @@ (rx/do done) (rx/map (constantly fetch-profile))))) +(s/def ::file #(instance? js/File %)) + (defn update-photo ([file] (update-photo file (constantly nil))) ([file done] - {:pre [(us/file? file) - (fn? done)]} + (us/assert ::file file) + (us/assert fn? done) (UpdatePhoto. file done))) diff --git a/frontend/src/uxbox/main/data/workspace.cljs b/frontend/src/uxbox/main/data/workspace.cljs index 820c3fc79..acf736c14 100644 --- a/frontend/src/uxbox/main/data/workspace.cljs +++ b/frontend/src/uxbox/main/data/workspace.cljs @@ -11,6 +11,7 @@ [potok.core :as ptk] [uxbox.common.data :as d] [uxbox.common.pages :as cp] + [uxbox.common.spec :as us] [uxbox.config :as cfg] [uxbox.main.constants :as c] [uxbox.main.data.icons :as udi] @@ -28,7 +29,6 @@ [uxbox.util.math :as mth] [uxbox.util.perf :as perf] [uxbox.util.router :as rt] - [uxbox.util.spec :as us] [uxbox.util.time :as dt] [uxbox.util.transit :as t] [uxbox.util.uuid :as uuid] @@ -130,7 +130,7 @@ (defn handle-who [{:keys [users] :as msg}] - (s/assert set? users) + (us/assert set? users) (ptk/reify ::handle-who ptk/UpdateEvent (update [_ state] @@ -195,8 +195,8 @@ (defn initialize "Initialize the workspace state." [file-id page-id] - (s/assert ::us/uuid file-id) - (s/assert ::us/uuid page-id) + (us/assert ::us/uuid file-id) + (us/assert ::us/uuid page-id) (ptk/reify ::initialize ptk/WatchEvent (watch [_ state stream] @@ -218,7 +218,7 @@ (defn- initialized [file-id] - (s/assert ::us/uuid file-id) + (us/assert ::us/uuid file-id) (ptk/reify ::initialized ptk/UpdateEvent (update [_ state] @@ -231,8 +231,8 @@ (defn finalize [file-id page-id] - (s/assert ::us/uuid file-id) - (s/assert ::us/uuid page-id) + (us/assert ::us/uuid file-id) + (us/assert ::us/uuid page-id) (ptk/reify ::finalize ptk/UpdateEvent (update [_ state] @@ -289,7 +289,7 @@ (defn toggle-layout-flag [flag] - (s/assert keyword? flag) + (us/assert keyword? flag) (ptk/reify ::toggle-layout-flag ptk/UpdateEvent (update [_ state] @@ -303,7 +303,7 @@ (defn activate-flag [flag] - (s/assert keyword? flag) + (us/assert keyword? flag) (ptk/reify ::activate-flag ptk/UpdateEvent (update [_ state] @@ -315,7 +315,7 @@ (defn deactivate-flag [flag] - (s/assert keyword? flag) + (us/assert keyword? flag) (ptk/reify ::deactivate-flag ptk/UpdateEvent (update [_ state] @@ -323,7 +323,7 @@ (defn toggle-flag [flag] - (s/assert keyword? flag) + (us/assert keyword? flag) (ptk/reify ::toggle-flag ptk/WatchEvent (watch [_ state stream] @@ -483,7 +483,7 @@ ;; (defn initialize-alignment ;; [id] -;; (s/assert ::us/uuid id) +;; (us/assert ::us/uuid id) ;; (ptk/reify ::initialize-alignment ;; ptk/WatchEvent ;; (watch [_ state stream] @@ -541,7 +541,7 @@ (defn add-shape [data] - (s/assert ::shape-attrs data) + (us/assert ::shape-attrs data) (let [id (uuid/random)] (ptk/reify ::add-shape ptk/UpdateEvent @@ -570,7 +570,7 @@ (defn add-canvas [data] - (s/assert ::shape-attrs data) + (us/assert ::shape-attrs data) (let [id (uuid/random)] (ptk/reify ::add-canvas ptk/UpdateEvent @@ -621,7 +621,7 @@ (defn select-shape [id] - (s/assert ::us/uuid id) + (us/assert ::us/uuid id) (ptk/reify ::select-shape ptk/UpdateEvent (update [_ state] @@ -683,8 +683,8 @@ (defn update-shape [id attrs] - (s/assert ::us/uuid id) - (s/assert ::shape-attrs attrs) + (us/assert ::us/uuid id) + (us/assert ::shape-attrs attrs) (ptk/reify ::update-shape IBatchedChange ptk/UpdateEvent @@ -704,7 +704,7 @@ (defn update-options [opts] - (s/assert ::cp/options opts) + (us/assert ::cp/options opts) (ptk/reify ::update-options IBatchedChange ptk/UpdateEvent @@ -763,8 +763,8 @@ (defn move-selected [direction align?] - (s/assert ::direction direction) - (s/assert boolean? align?) + (us/assert ::direction direction) + (us/assert boolean? align?) (ptk/reify ::move-selected ptk/WatchEvent @@ -816,8 +816,8 @@ (defn rename-shape [id name] - (s/assert ::us/uuid id) - (s/assert string? name) + (us/assert ::us/uuid id) + (us/assert string? name) (ptk/reify ::rename-shape ptk/UpdateEvent (update [_ state] @@ -838,7 +838,7 @@ (defn order-selected-shapes [loc] - (s/assert ::direction loc) + (us/assert ::direction loc) (ptk/reify ::move-selected-layer ptk/UpdateEvent (update [_ state] @@ -867,8 +867,8 @@ (defn temporal-shape-order-change [id index] - (s/assert ::us/uuid id) - (s/assert number? index) + (us/assert ::us/uuid id) + (us/assert number? index) (ptk/reify ::change-shape-order ptk/UpdateEvent (update [_ state] @@ -896,8 +896,8 @@ (defn change-canvas-order [{:keys [id index] :as params}] - (s/assert ::us/uuid id) - (s/assert ::us/number index) + (us/assert ::us/uuid id) + (us/assert ::us/number index) (ptk/reify ::change-canvas-order ptk/UpdateEvent (update [_ state] @@ -912,7 +912,7 @@ (defn initial-selection-align "Align the selection of shapes." [ids] - (s/assert ::set-of-uuid ids) + (us/assert ::set-of-uuid ids) (ptk/reify ::initialize-shapes-align-in-bulk ptk/WatchEvent (watch [_ state stream] @@ -929,8 +929,8 @@ (defn assoc-temporal-modifier-in-bulk [ids xfmt] - (s/assert ::set-of-uuid ids) - (s/assert gmt/matrix? xfmt) + (us/assert ::set-of-uuid ids) + (us/assert gmt/matrix? xfmt) (ptk/reify ::assoc-temporal-modifier-in-bulk ptk/UpdateEvent (update [_ state] @@ -940,8 +940,8 @@ "Apply the same displacement delta to all shapes identified by the set if ids." [ids delta] - (s/assert ::set-of-uuid ids) - (s/assert gpt/point? delta) + (us/assert ::set-of-uuid ids) + (us/assert gpt/point? delta) (letfn [(process-shape [state id] (let [prev (get-in state [:workspace-data :shapes-by-id id :modifier-mtx] (gmt/matrix)) xfmt (gmt/translate prev delta)] @@ -989,7 +989,7 @@ (defn commit-changes [changes] - (s/assert ::cp/changes changes) + (us/assert ::cp/changes changes) (ptk/reify ::commit-changes ptk/UpdateEvent (update [_ state] @@ -1019,7 +1019,7 @@ (defn shapes-changes-commited [{:keys [page-id version changes] :as params}] - (s/assert ::shapes-changes-commited params) + (us/assert ::shapes-changes-commited params) (ptk/reify ::shapes-changes-commited ptk/UpdateEvent (update [_ state] @@ -1089,8 +1089,8 @@ of the shape using the width and height attrs instread final point of coordinates." [id dimensions] - (s/assert ::us/uuid id) - (s/assert ::update-dimensions dimensions) + (us/assert ::us/uuid id) + (us/assert ::update-dimensions dimensions) (ptk/reify ::update-dimensions ptk/UpdateEvent (update [_ state] @@ -1113,8 +1113,8 @@ (defn update-position [id point] - (s/assert ::us/uuid id) - (s/assert gpt/point? point) + (us/assert ::us/uuid id) + (us/assert gpt/point? point) (ptk/reify ::update-position ptk/UpdateEvent (update [_ state] @@ -1159,8 +1159,8 @@ ;; TODO: revisit (defn set-hidden-attr [id value] - (s/assert ::us/uuid id) - (s/assert ::us/boolean value) + (us/assert ::us/uuid id) + (us/assert ::us/boolean value) (letfn [(impl-set-hidden [state id] (let [{:keys [type] :as shape} (get-in state [:shapes id])] (as-> state $ @@ -1182,8 +1182,8 @@ ;; TODO: revisit (defn set-blocked-attr [id value] - (s/assert ::us/uuid id) - (s/assert ::us/boolean value) + (us/assert ::us/uuid id) + (us/assert ::us/boolean value) (letfn [(impl-set-blocked [state id] (let [{:keys [type] :as shape} (get-in state [:shapes id])] (as-> state $ @@ -1245,7 +1245,7 @@ (defn select-canvas [id] - (s/assert ::us/uuid id) + (us/assert ::us/uuid id) (ptk/reify ::select-canvas ptk/UpdateEvent (update [_ state] @@ -1266,7 +1266,7 @@ (defn go-to-page [page-id] - (s/assert ::us/uuid page-id) + (us/assert ::us/uuid page-id) (ptk/reify ::go-to ptk/WatchEvent (watch [_ state stream] diff --git a/frontend/src/uxbox/main/ui/auth/login.cljs b/frontend/src/uxbox/main/ui/auth/login.cljs index 5510e02f2..31c654871 100644 --- a/frontend/src/uxbox/main/ui/auth/login.cljs +++ b/frontend/src/uxbox/main/ui/auth/login.cljs @@ -9,6 +9,7 @@ (:require [cljs.spec.alpha :as s] [rumext.alpha :as mf] + [uxbox.common.spec :as us] [uxbox.builtins.icons :as i] [uxbox.config :as cfg] [uxbox.main.data.auth :as da] @@ -17,8 +18,7 @@ [uxbox.util.dom :as dom] [uxbox.util.forms :as fm] [uxbox.util.i18n :refer [tr]] - [uxbox.util.router :as rt] - [uxbox.util.spec :as us])) + [uxbox.util.router :as rt])) (s/def ::username ::us/not-empty-string) (s/def ::password ::us/not-empty-string) diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs index 8df360ec0..20d79ef22 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs @@ -17,8 +17,7 @@ [uxbox.main.ui.lightbox :as lbx] [uxbox.util.data :refer [read-string]] [uxbox.util.dom :as dom] - [uxbox.util.i18n :refer [tr]] - [uxbox.util.spec :refer [color?]])) + [uxbox.util.i18n :refer [tr]])) ;; --- Helpers diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options/page.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options/page.cljs index c504d3ed5..43e1b8b18 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar/options/page.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options/page.cljs @@ -21,8 +21,7 @@ [uxbox.main.ui.workspace.colorpicker :refer [colorpicker-modal]] [uxbox.util.data :refer [parse-int]] [uxbox.util.dom :as dom] - [uxbox.util.i18n :refer [tr]] - [uxbox.util.spec :refer [color?]])) + [uxbox.util.i18n :refer [tr]])) ;; (mf/defc metadata-options ;; [{:keys [page] :as props}] diff --git a/frontend/src/uxbox/main/websockets.cljs b/frontend/src/uxbox/main/websockets.cljs index 27a691b7a..5086a66e4 100644 --- a/frontend/src/uxbox/main/websockets.cljs +++ b/frontend/src/uxbox/main/websockets.cljs @@ -7,11 +7,9 @@ (ns uxbox.main.websockets "A interface to webworkers exposed functionality." (:require - [cljs.spec.alpha :as s] [goog.events :as ev] [beicon.core :as rx] - [potok.core :as ptk] - [uxbox.util.spec :as us]) + [potok.core :as ptk]) (:import goog.net.WebSocket goog.net.WebSocket.EventType)) diff --git a/frontend/src/uxbox/main/workers.cljs b/frontend/src/uxbox/main/workers.cljs index ba9cf85c3..a2dd727e8 100644 --- a/frontend/src/uxbox/main/workers.cljs +++ b/frontend/src/uxbox/main/workers.cljs @@ -9,7 +9,7 @@ (:require [cljs.spec.alpha :as s] [beicon.core :as rx] [potok.core :as ptk] - [uxbox.util.spec :as us] + [uxbox.common.spec :as us] [uxbox.util.workers :as uw])) (s/def ::width number?) @@ -36,6 +36,6 @@ (defn initialize-alignment [params] - {:pre [(us/valid? ::initialize-alignment-params params)]} + (us/assert ::initialize-alignment-params params) (let [message (assoc params :cmd :grid-init)] (uw/send! worker message))) diff --git a/frontend/src/uxbox/util/forms.cljs b/frontend/src/uxbox/util/forms.cljs index 02f91253f..a27054547 100644 --- a/frontend/src/uxbox/util/forms.cljs +++ b/frontend/src/uxbox/util/forms.cljs @@ -13,8 +13,8 @@ [lentes.core :as l] [potok.core :as ptk] [rumext.alpha :as mf] + [uxbox.common.spec :as us] [uxbox.util.dom :as dom] - [uxbox.util.spec :as us] [uxbox.util.i18n :refer [tr]])) ;; --- Handlers Helpers @@ -119,4 +119,3 @@ (s/def ::email ::us/email) (s/def ::not-empty-string ::us/not-empty-string) (s/def ::color ::us/color) -(s/def ::number-str ::us/number-str) diff --git a/frontend/src/uxbox/util/spec.cljs b/frontend/src/uxbox/util/spec.cljs deleted file mode 100644 index 4bbe132f7..000000000 --- a/frontend/src/uxbox/util/spec.cljs +++ /dev/null @@ -1,103 +0,0 @@ -;; 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) 2015-2016 Andrey Antukh <niwi@niwi.nz> - -(ns uxbox.util.spec - (:require [cljs.spec.alpha :as s] - [cuerdas.core :as str])) - - -;; --- Constants - -(def email-rx - #"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$") - -(def uuid-rx - #"^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$") - -(def number-rx - #"^[+-]?([0-9]*\.?[0-9]+|[0-9]+\.?[0-9]*)([eE][+-]?[0-9]+)?$") - -(def ^:private color-re - #"^#[0-9A-Fa-f]{6}$") - -;; --- Predicates - -(defn email? - [v] - (and (string? v) - (re-matches email-rx v))) - -(defn color? - [v] - (and (string? v) - (re-matches #"^#[0-9A-Fa-f]{6}$" v))) - -(defn file? - [v] - (instance? js/File v)) - -(defn url-str? - [v] - (string? v)) - -;; --- Default Specs - -(s/def ::bool boolean?) -(s/def ::uuid uuid?) -(s/def ::email email?) -(s/def ::color color?) -(s/def ::string string?) -(s/def ::positive pos?) -(s/def ::inst inst?) -(s/def ::keyword keyword?) -(s/def ::fn fn?) -(s/def ::set set?) -(s/def ::coll coll?) - -(s/def ::not-empty-string - (s/and string? #(not (str/empty? %)))) - - -(defn- conform-number - [v] - (cond - (number? v) v - (and (string? v) (re-matches number-rx v)) (js/parseFloat v) - :else ::s/invalid)) - -(s/def ::number - (s/conformer conform-number str)) - -;; NOTE: backward compatibility (revisit the code and remove) -(s/def ::number-str ::number) - -(s/def ::color color?) - -;; --- Public Api - -(defn valid? - [spec data] - (let [valid (s/valid? spec data)] - (when-not valid - (js/console.error (str "Spec validation error:\n" (s/explain-str spec data)))) - valid)) - -(defn extract - "Given a map spec, performs a `select-keys` - like exctraction from the object. - - NOTE: this function does not executes - the conform or validation of the data, - is responsability of the user to do it." - [data spec] - (let [desc (s/describe spec) - {:keys [req-un opt-un]} (apply hash-map (rest desc)) - keys (concat - (map (comp keyword name) req-un) - (map (comp keyword name) opt-un))] - (select-keys data keys))) - -