diff --git a/backend/src/app/binfile/common.clj b/backend/src/app/binfile/common.clj index b4d7bafdcb..1781860c05 100644 --- a/backend/src/app/binfile/common.clj +++ b/backend/src/app/binfile/common.clj @@ -633,7 +633,7 @@ (dissoc :team-id) (dissoc :migrations))) -(defn file->file-data-params +(defn- file->file-data-params [{:keys [id] :as file} & {:as opts}] (let [created-at (or (:created-at file) (ct/now)) modified-at (or (:modified-at file) created-at)] diff --git a/backend/src/app/features/fdata.clj b/backend/src/app/features/fdata.clj index 6a4bebe243..16afb9fd1a 100644 --- a/backend/src/app/features/fdata.clj +++ b/backend/src/app/features/fdata.clj @@ -172,16 +172,24 @@ (= backend "legacy-db") (cond (= type "main") - (db/update! cfg :file - {:data data} - {:id file-id} - {::db/return-keys false}) + (do + (db/delete! cfg :file-data + {:id id :file-id file-id :type "main"} + {::db/return-keys false}) + (db/update! cfg :file + {:data data} + {:id file-id} + {::db/return-keys false})) (= type "snapshot") - (db/update! cfg :file-change - {:data data} - {:file-id file-id :id id} - {::db/return-keys false}) + (do + (db/delete! cfg :file-data + {:id id :file-id file-id :type "snapshot"} + {::db/return-keys false}) + (db/update! cfg :file-change + {:data data} + {:file-id file-id :id id} + {::db/return-keys false})) (= type "fragment") (upsert-in-database cfg diff --git a/backend/src/data_readers.clj b/backend/src/data_readers.clj index e32d7c506c..dd94d1aae7 100644 --- a/backend/src/data_readers.clj +++ b/backend/src/data_readers.clj @@ -4,7 +4,7 @@ penpot/path-data app.common.types.path/from-string penpot/matrix app.common.geom.matrix/decode-matrix penpot/point app.common.geom.point/decode-point - penpot/token-lib app.common.types.tokens-lib/parse-multi-set-dtcg-json + penpot/tokens-lib app.common.types.tokens-lib/parse-multi-set-dtcg-json penpot/token-set app.common.types.tokens-lib/make-token-set penpot/token-theme app.common.types.tokens-lib/make-token-theme penpot/token app.common.types.tokens-lib/make-token} diff --git a/common/src/app/common/files/migrations.cljc b/common/src/app/common/files/migrations.cljc index 91f5793e99..10425d4e49 100644 --- a/common/src/app/common/files/migrations.cljc +++ b/common/src/app/common/files/migrations.cljc @@ -75,7 +75,9 @@ data (-> data (assoc :id id) - (dissoc :version :libs))] + (dissoc :version) + (dissoc :libs) + (ctf/check-file-data))] (-> file (assoc :data data) diff --git a/common/src/app/common/types/file.cljc b/common/src/app/common/types/file.cljc index b037831626..87e6ee739b 100644 --- a/common/src/app/common/types/file.cljc +++ b/common/src/app/common/types/file.cljc @@ -114,10 +114,10 @@ (sm/register! ::typographies schema:typographies) (def check-file - (sm/check-fn schema:file :hint "check error on validating file")) + (sm/check-fn schema:file :hint "invalid file")) (def check-file-data - (sm/check-fn schema:data)) + (sm/check-fn schema:data :hint "invalid file data")) (def check-file-media (sm/check-fn schema:media)) diff --git a/common/src/app/common/types/tokens_lib.cljc b/common/src/app/common/types/tokens_lib.cljc index 9191aa3a2f..df7aa38cf2 100644 --- a/common/src/app/common/types/tokens_lib.cljc +++ b/common/src/app/common/types/tokens_lib.cljc @@ -27,6 +27,10 @@ ;; === Common +(defprotocol IValidation + (valid? [_] "check if this data structure is valid, returns true or false") + (check [_] "check if this data structure is valid, raises exception or self")) + (defprotocol INamedItem "Protocol for items that have an id, a name, a description and a modified date." (get-id [_] "Get the id of the item.") @@ -536,12 +540,6 @@ [:fn d/ordered-map?] [:fn not-repeated-ids]]) -(def ^:private check-token-sets - (sm/check-fn schema:token-sets :hint "expected valid token sets")) - -(def ^:private valid-token-sets? - (sm/validator schema:token-sets)) - ;; === TokenTheme (defprotocol ITokenTheme @@ -770,21 +768,9 @@ [:fn d/ordered-map?]]] [:fn d/ordered-map?]]) -(def ^:private check-token-themes - (sm/check-fn schema:token-themes :hint "expected valid token themes")) - -(def ^:private valid-token-themes? - (sm/validator schema:token-themes)) - (def ^:private schema:active-themes [:set :string]) -(def ^:private check-active-themes - (sm/check-fn schema:active-themes :hint "expected valid active themes")) - -(def ^:private valid-active-token-themes? - (sm/validator schema:active-themes)) - (defn walk-sets-tree-seq "Walk sets tree as a flat list. @@ -900,6 +886,8 @@ ;; === Tokens Lib (declare make-tokens-lib) +(declare ^:private check-tokens-lib-map) +(declare ^:private valid-tokens-lib-map?) (defprotocol ITokensLib "A library of tokens, sets and themes." @@ -920,8 +908,7 @@ Will return a value that matches this schema: `:partial` Mixed active state of nested sets") (get-tokens-in-active-sets [_] "set of set names that are active in the the active themes") (get-all-tokens [_] "all tokens in the lib") - (get-tokens [_ set-id] "return a map of tokens in the set, indexed by token-name") - (validate [_])) + (get-tokens [_ set-id] "return a map of tokens in the set, indexed by token-name")) (declare parse-multi-set-dtcg-json) (declare export-dtcg-json) @@ -1323,14 +1310,17 @@ Will return a value that matches this schema: (get-set set-id) (get-tokens-))) - (validate [_] - (and (valid-token-sets? sets) - (valid-token-themes? themes) - (valid-active-token-themes? active-themes)))) + IValidation + (valid? [this] + (valid-tokens-lib-map? (datafy this))) + + (check [this] + (check-tokens-lib-map (datafy this)) + this)) (defmethod pp/simple-dispatch TokensLib [^TokensLib obj] - (.write *out* "#penpot/token-lib ") + (.write *out* "#penpot/tokens-lib ") (pp/pprint-newline :miser) (pp/pprint (export-dtcg-json obj))) @@ -1338,7 +1328,7 @@ Will return a value that matches this schema: (do (defmethod print-method TokensLib [^TokensLib obj ^java.io.Writer w] - (.write w "#penpot/token-lib ") + (.write w "#penpot/tokens-lib ") (print-method (export-dtcg-json obj) w)) (defmethod print-dup TokensLib @@ -1349,16 +1339,29 @@ Will return a value that matches this schema: (extend-type TokensLib cljs.core/IPrintWithWriter (-pr-writer [this writer opts] - (-write writer "#penpot/token-lib ") + (-write writer "#penpot/tokens-lib ") (-pr-writer (export-dtcg-json this) writer opts)) cljs.core/IEncodeJS (-clj->js [this] (clj->js (datafy this))))) +(def ^:private schema:tokens-lib-map + "Internal data structure schema" + [:map {:title "TokensLib"} + [:sets schema:token-sets] + [:themes schema:token-themes] + [:active-themes schema:active-themes]]) + +(def ^:private valid-tokens-lib-map? + (sm/lazy-validator schema:tokens-lib-map)) + +(def ^:private check-tokens-lib-map + (sm/check-fn schema:tokens-lib-map :hint "invalid tokens-lib internal data structure")) + (defn valid-tokens-lib? [o] (and (instance? TokensLib o) - (validate o))) + (valid? o))) (defn- ensure-hidden-theme "A helper that is responsible to ensure that the hidden theme always @@ -1379,15 +1382,14 @@ Will return a value that matches this schema: (defn make-tokens-lib "Make a new instance of TokensLib from a map and validates the input" - [& {:keys [sets themes active-themes]}] - (let [sets (or sets (d/ordered-map)) - themes (-> (or themes (d/ordered-map)) - (ensure-hidden-theme)) - active-themes (or active-themes #{hidden-theme-path})] - (TokensLib. - (check-token-sets sets) - (check-token-themes themes) - (check-active-themes active-themes)))) + [& {:as params}] + (-> params + (update :sets #(or % (d/ordered-map))) + (update :themes #(-> (or % (d/ordered-map)) + (ensure-hidden-theme))) + (update :active-themes #(or % #{hidden-theme-path})) + (check-tokens-lib-map) + (map->tokens-lib))) (defn ensure-tokens-lib [tokens-lib] @@ -1902,7 +1904,8 @@ Will return a value that matches this schema: (some-> tokens-lib (-> (datafy) (update :sets d/update-vals migrate-set-node) - (map->tokens-lib))))) + (map->tokens-lib) + (check))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; SERIALIZATION (FRESIAN) diff --git a/common/test/common_tests/files_migrations_test.cljc b/common/test/common_tests/files_migrations_test.cljc index f5fe884ba8..d9de5e84f2 100644 --- a/common/test/common_tests/files_migrations_test.cljc +++ b/common/test/common_tests/files_migrations_test.cljc @@ -9,6 +9,7 @@ [app.common.data :as d] [app.common.files.migrations :as cfm] [app.common.pprint :as pp] + [app.common.types.file :as ctf] [clojure.test :as t])) (defmethod cfm/migrate-data "test/1" [data _] (update data :sum inc)) @@ -17,7 +18,8 @@ (t/deftest generic-migration-subsystem-1 (let [migrations (into (d/ordered-set) ["test/1" "test/2" "test/3"])] - (with-redefs [cfm/available-migrations migrations] + (with-redefs [cfm/available-migrations migrations + ctf/check-file-data identity] (let [file {:data {:sum 1} :id 1 :migrations (d/ordered-set "test/1")} diff --git a/common/test/common_tests/types/tokens_lib_test.cljc b/common/test/common_tests/types/tokens_lib_test.cljc index 4b86480e12..f036c821df 100644 --- a/common/test/common_tests/types/tokens_lib_test.cljc +++ b/common/test/common_tests/types/tokens_lib_test.cljc @@ -241,7 +241,7 @@ (t/deftest make-invalid-tokens-lib (let [params {:sets {} :themes {}}] - (t/is (thrown-with-msg? #?(:cljs js/Error :clj Exception) #"expected valid token sets" + (t/is (thrown-with-msg? #?(:cljs js/Error :clj Exception) #"invalid tokens-lib internal data structure" (ctob/make-tokens-lib params))))) (t/deftest add-token-set-to-token-lib