Fix single set import

This commit is contained in:
Andrey Fedorov 2025-03-31 18:38:17 +02:00 committed by Andrés Moya
parent 982118c942
commit a20dd3f955
6 changed files with 127 additions and 50 deletions

View file

@ -665,20 +665,20 @@
["$value" :map] ["$value" :map]
["$type" :string]]])) ["$type" :string]]]))
(defn has-legacy-format? (defn get-json-format
"Searches through parsed token file and returns: "Searches through parsed token file and returns:
- true when first node satisfies `legacy-node?` predicate - `:json-format/legacy` when first node satisfies `legacy-node?` predicate
- false when first node satisfies `dtcg-node?` predicate - `:json-format/dtcg` when first node satisfies `dtcg-node?` predicate
- nil if neither combination is found" - `nil` if neither combination is found"
([data] ([data]
(has-legacy-format? data legacy-node? dtcg-node?)) (get-json-format data legacy-node? dtcg-node?))
([data legacy-node? dtcg-node?] ([data legacy-node? dtcg-node?]
(let [branch? map? (let [branch? map?
children (fn [node] (vals node)) children (fn [node] (vals node))
check-node (fn [node] check-node (fn [node]
(cond (cond
(legacy-node? node) true (legacy-node? node) :json-format/legacy
(dtcg-node? node) false (dtcg-node? node) :json-format/dtcg
:else nil)) :else nil))
walk (fn walk [node] walk (fn walk [node]
(lazy-seq (lazy-seq
@ -690,6 +690,10 @@
(filter some?) (filter some?)
first)))) first))))
(defn single-set? [data]
(and (not (contains? data "$metadata"))
(not (contains? data "$themes"))))
;; DEPRECATED ;; DEPRECATED
(defn walk-sets-tree-seq (defn walk-sets-tree-seq
"Walk sets tree as a flat list. "Walk sets tree as a flat list.
@ -826,6 +830,24 @@
(declare make-tokens-lib) (declare make-tokens-lib)
(defn- legacy-nodes->dtcg-nodes [sets-data]
(walk/postwalk
(fn [node]
(cond-> node
(and (map? node)
(contains? node "value")
(sequential? (get node "value")))
(update "value"
(fn [seq-value]
(map #(set/rename-keys % {"type" "$type"}) seq-value)))
(and (map? node)
(and (contains? node "type")
(contains? node "value")))
(set/rename-keys {"value" "$value"
"type" "$type"})))
sets-data))
(defprotocol ITokensLib (defprotocol ITokensLib
"A library of tokens, sets and themes." "A library of tokens, sets and themes."
(set-path-exists? [_ path] "if a set at `path` exists") (set-path-exists? [_ path] "if a set at `path` exists")
@ -844,6 +866,8 @@ Will return a value that matches this schema:
(get-active-themes-set-tokens [_] "set of set names that are active in the the active themes") (get-active-themes-set-tokens [_] "set of set names that are active in the the active themes")
(encode-dtcg [_] "Encodes library to a dtcg compatible json string") (encode-dtcg [_] "Encodes library to a dtcg compatible json string")
(decode-dtcg-json [_ parsed-json] "Decodes parsed json containing tokens and converts to library") (decode-dtcg-json [_ parsed-json] "Decodes parsed json containing tokens and converts to library")
(decode-single-set-json [_ set-name tokens] "Decodes parsed json containing single token set and converts to library")
(decode-single-set-legacy-json [_ set-name tokens] "Decodes parsed legacy json containing single token set and converts to library")
(decode-legacy-json [_ parsed-json] "Decodes parsed legacy json containing tokens and converts to library") (decode-legacy-json [_ parsed-json] "Decodes parsed legacy json containing tokens and converts to library")
(get-all-tokens [_] "all tokens in the lib") (get-all-tokens [_] "all tokens in the lib")
(validate [_])) (validate [_]))
@ -1287,6 +1311,17 @@ Will return a value that matches this schema:
(assoc-in ["$metadata" "activeThemes"] active-themes-clear) (assoc-in ["$metadata" "activeThemes"] active-themes-clear)
(assoc-in ["$metadata" "activeSets"] active-sets)))) (assoc-in ["$metadata" "activeSets"] active-sets))))
(decode-single-set-json [this set-name tokens]
(assert (map? tokens) "expected a map data structure for `data`")
(add-set this (make-token-set :name (normalize-set-name set-name)
:tokens (flatten-nested-tokens-json tokens ""))))
(decode-single-set-legacy-json [this set-name tokens]
(assert (map? tokens) "expected a map data structure for `data`")
(decode-single-set-json this set-name (legacy-nodes->dtcg-nodes tokens)))
(decode-dtcg-json [_ data] (decode-dtcg-json [_ data]
(assert (map? data) "expected a map data structure for `data`") (assert (map? data) "expected a map data structure for `data`")
@ -1370,22 +1405,7 @@ Will return a value that matches this schema:
(decode-legacy-json [this parsed-legacy-json] (decode-legacy-json [this parsed-legacy-json]
(let [other-data (select-keys parsed-legacy-json ["$themes" "$metadata"]) (let [other-data (select-keys parsed-legacy-json ["$themes" "$metadata"])
sets-data (dissoc parsed-legacy-json "$themes" "$metadata") sets-data (dissoc parsed-legacy-json "$themes" "$metadata")
dtcg-sets-data (walk/postwalk dtcg-sets-data (legacy-nodes->dtcg-nodes sets-data)]
(fn [node]
(cond-> node
(and (map? node)
(contains? node "value")
(sequential? (get node "value")))
(update "value"
(fn [seq-value]
(map #(set/rename-keys % {"type" "$type"}) seq-value)))
(and (map? node)
(and (contains? node "type")
(contains? node "value")))
(set/rename-keys {"value" "$value"
"type" "$type"})))
sets-data)]
(decode-dtcg-json this (merge other-data (decode-dtcg-json this (merge other-data
dtcg-sets-data)))) dtcg-sets-data))))
(get-all-tokens [this] (get-all-tokens [this]

View file

@ -0,0 +1,6 @@
{"color":
{"red":
{"100":
{"value":"red",
"type":"color",
"description":""}}}}

View file

@ -0,0 +1,6 @@
{"color":
{"red":
{"100":
{"$value":"red",
"$type":"color",
"$description":""}}}}

View file

@ -1371,6 +1371,30 @@
(t/testing "invalid tokens got discarded" (t/testing "invalid tokens got discarded"
(t/is (nil? (get-set-token "typography" "H1.Bold"))))))) (t/is (nil? (get-set-token "typography" "H1.Bold")))))))
#?(:clj
(t/deftest single-set-legacy-json-decoding
(let [json (-> (slurp "test/common_tests/types/data/legacy-single-set.json")
(tr/decode-str))
lib (ctob/decode-single-set-legacy-json (ctob/ensure-tokens-lib nil) "single_set" json)
get-set-token (fn [set-name token-name]
(some-> (ctob/get-set lib set-name)
(ctob/get-token token-name)))]
(t/is (= '("single_set") (ctob/get-ordered-set-names lib)))
(t/testing "token added"
(t/is (some? (get-set-token "single_set" "color.red.100")))))))
#?(:clj
(t/deftest single-set-dtcg-json-decoding
(let [json (-> (slurp "test/common_tests/types/data/single-set.json")
(tr/decode-str))
lib (ctob/decode-single-set-json (ctob/ensure-tokens-lib nil) "single_set" json)
get-set-token (fn [set-name token-name]
(some-> (ctob/get-set lib set-name)
(ctob/get-token token-name)))]
(t/is (= '("single_set") (ctob/get-ordered-set-names lib)))
(t/testing "token added"
(t/is (some? (get-set-token "single_set" "color.red.100")))))))
#?(:clj #?(:clj
(t/deftest dtcg-encoding-decoding-json (t/deftest dtcg-encoding-decoding-json
(let [json (-> (slurp "test/common_tests/types/data/tokens-multi-set-example.json") (let [json (-> (slurp "test/common_tests/types/data/tokens-multi-set-example.json")

View file

@ -40,6 +40,7 @@
[app.util.i18n :refer [tr]] [app.util.i18n :refer [tr]]
[app.util.webapi :as wapi] [app.util.webapi :as wapi]
[beicon.v2.core :as rx] [beicon.v2.core :as rx]
[cuerdas.core :as str]
[okulary.core :as l] [okulary.core :as l]
[potok.v2.core :as ptk] [potok.v2.core :as ptk]
[rumext.v2 :as mf] [rumext.v2 :as mf]
@ -367,9 +368,10 @@
(fn [event] (fn [event]
(let [file (-> (dom/get-target event) (let [file (-> (dom/get-target event)
(dom/get-files) (dom/get-files)
(first))] (first))
file-name (str/replace (.-name file) ".json" "")]
(->> (wapi/read-file-as-text file) (->> (wapi/read-file-as-text file)
(sd/process-json-stream) (sd/process-json-stream {:file-name file-name})
(rx/subs! (fn [lib] (rx/subs! (fn [lib]
(st/emit! (ptk/data-event ::ev/event {::ev/name "import-tokens"}) (st/emit! (ptk/data-event ::ev/event {::ev/name "import-tokens"})
(dt/import-tokens-lib lib))) (dt/import-tokens-lib lib)))

View file

@ -6,6 +6,7 @@
[app.common.schema :as sm] [app.common.schema :as sm]
[app.common.transit :as t] [app.common.transit :as t]
[app.common.types.tokens-lib :as ctob] [app.common.types.tokens-lib :as ctob]
[app.main.refs :as refs]
[app.main.ui.workspace.tokens.errors :as wte] [app.main.ui.workspace.tokens.errors :as wte]
[app.main.ui.workspace.tokens.tinycolor :as tinycolor] [app.main.ui.workspace.tokens.tinycolor :as tinycolor]
[app.main.ui.workspace.tokens.token :as wtt] [app.main.ui.workspace.tokens.token :as wtt]
@ -249,7 +250,11 @@
(= header-2 "Reference Errors:")) (= header-2 "Reference Errors:"))
errors))) errors)))
(defn process-json-stream [data-stream] (defn process-json-stream
([data-stream]
(process-json-stream nil data-stream))
([params data-stream]
(let [{:keys [file-name]} params]
(->> data-stream (->> data-stream
(rx/map (fn [data] (rx/map (fn [data]
(try (try
@ -257,12 +262,26 @@
(catch js/Error e (catch js/Error e
(throw (wte/error-ex-info :error.import/json-parse-error data e)))))) (throw (wte/error-ex-info :error.import/json-parse-error data e))))))
(rx/map (fn [json-data] (rx/map (fn [json-data]
(let [single-set? (ctob/single-set? json-data)
json-format (ctob/get-json-format json-data)]
(try (try
(if-not (ctob/has-legacy-format? json-data) (cond
(ctob/decode-dtcg-json (ctob/ensure-tokens-lib nil) json-data) (and single-set?
(ctob/decode-legacy-json (ctob/ensure-tokens-lib nil) json-data)) (= :json-format/legacy json-format))
(ctob/decode-single-set-legacy-json (ctob/ensure-tokens-lib (deref refs/tokens-lib)) file-name json-data)
(and single-set?
(= :json-format/dtcg json-format))
(ctob/decode-single-set-json (ctob/ensure-tokens-lib (deref refs/tokens-lib)) file-name json-data)
(= :json-format/legacy json-format)
(ctob/decode-legacy-json (ctob/ensure-tokens-lib nil) json-data)
:else
(ctob/decode-dtcg-json (ctob/ensure-tokens-lib nil) json-data))
(catch js/Error e (catch js/Error e
(throw (wte/error-ex-info :error.import/invalid-json-data json-data e)))))) (throw (wte/error-ex-info :error.import/invalid-json-data json-data e)))))))
(rx/mapcat (fn [tokens-lib] (rx/mapcat (fn [tokens-lib]
(try (try
(-> (ctob/get-all-tokens tokens-lib) (-> (ctob/get-all-tokens tokens-lib)
@ -275,7 +294,7 @@
(wte/error-ex-info :error.import/style-dictionary-unknown-error sd-error sd-error))] (wte/error-ex-info :error.import/style-dictionary-unknown-error sd-error sd-error))]
(throw err))))) (throw err)))))
(catch js/Error e (catch js/Error e
(p/rejected (wte/error-ex-info :error.import/style-dictionary-unknown-error "" e)))))))) (p/rejected (wte/error-ex-info :error.import/style-dictionary-unknown-error "" e))))))))))
;; === Errors ;; === Errors