mirror of
https://github.com/penpot/penpot.git
synced 2025-12-11 22:14:05 +01:00
✨ Add reader tag support for tokens related types
This commit is contained in:
@@ -3,4 +3,8 @@
|
|||||||
penpot/duration app.common.time/duration
|
penpot/duration app.common.time/duration
|
||||||
penpot/path-data app.common.types.path/from-string
|
penpot/path-data app.common.types.path/from-string
|
||||||
penpot/matrix app.common.geom.matrix/decode-matrix
|
penpot/matrix app.common.geom.matrix/decode-matrix
|
||||||
penpot/point app.common.geom.point/decode-point}
|
penpot/point app.common.geom.point/decode-point
|
||||||
|
penpot/token-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}
|
||||||
|
|||||||
@@ -17,7 +17,9 @@
|
|||||||
[app.common.transit :as t]
|
[app.common.transit :as t]
|
||||||
[app.common.types.token :as cto]
|
[app.common.types.token :as cto]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[clojure.core.protocols :as protocols]
|
[clojure.core.protocols :as cp]
|
||||||
|
[clojure.datafy :refer [datafy]]
|
||||||
|
[clojure.pprint :as pp]
|
||||||
[clojure.set :as set]
|
[clojure.set :as set]
|
||||||
[clojure.walk :as walk]
|
[clojure.walk :as walk]
|
||||||
[cuerdas.core :as str]))
|
[cuerdas.core :as str]))
|
||||||
@@ -71,6 +73,9 @@
|
|||||||
;; === Token
|
;; === Token
|
||||||
|
|
||||||
(defrecord Token [id name type value description modified-at]
|
(defrecord Token [id name type value description modified-at]
|
||||||
|
cp/Datafiable
|
||||||
|
(datafy [this] (into {} this))
|
||||||
|
|
||||||
INamedItem
|
INamedItem
|
||||||
(get-name [_]
|
(get-name [_]
|
||||||
name)
|
name)
|
||||||
@@ -87,6 +92,34 @@
|
|||||||
(set-description [this new-description]
|
(set-description [this new-description]
|
||||||
(assoc this :description new-description)))
|
(assoc this :description new-description)))
|
||||||
|
|
||||||
|
(defmethod pp/simple-dispatch Token
|
||||||
|
[^Token obj]
|
||||||
|
(.write *out* "#penpot/token ")
|
||||||
|
(pp/pprint-newline :miser)
|
||||||
|
(pp/pprint (datafy obj)))
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
|
(do
|
||||||
|
(defmethod print-method Token
|
||||||
|
[^Token this ^java.io.Writer w]
|
||||||
|
(.write w "#penpot/token ")
|
||||||
|
(print-method (datafy this) w))
|
||||||
|
|
||||||
|
(defmethod print-dup Token
|
||||||
|
[^Token this ^java.io.Writer w]
|
||||||
|
(print-method this w)))
|
||||||
|
|
||||||
|
:cljs
|
||||||
|
(extend-type Token
|
||||||
|
cljs.core/IPrintWithWriter
|
||||||
|
(-pr-writer [this writer opts]
|
||||||
|
(-write writer "#penpot/token ")
|
||||||
|
(-pr-writer (datafy this) writer opts))
|
||||||
|
|
||||||
|
cljs.core/IEncodeJS
|
||||||
|
(-clj->js [this]
|
||||||
|
(clj->js (datafy this)))))
|
||||||
|
|
||||||
(defn token?
|
(defn token?
|
||||||
[o]
|
[o]
|
||||||
(instance? Token o))
|
(instance? Token o))
|
||||||
@@ -175,25 +208,26 @@
|
|||||||
(defrecord TokenSetLegacy [id name description modified-at tokens])
|
(defrecord TokenSetLegacy [id name description modified-at tokens])
|
||||||
|
|
||||||
(deftype TokenSet [id name description modified-at tokens]
|
(deftype TokenSet [id name description modified-at tokens]
|
||||||
#?@(:clj [clojure.lang.IDeref
|
Object
|
||||||
(deref [_] {:id id
|
(equals [_ other]
|
||||||
:name name
|
(and (instance? TokenSet other)
|
||||||
:description description
|
(= id (.-id ^TokenSet other))
|
||||||
:modified-at modified-at
|
(= name (.-name ^TokenSet other))
|
||||||
:tokens tokens})]
|
(= description (.-description ^TokenSet other))
|
||||||
:cljs [cljs.core/IDeref
|
(= modified-at (.-modified-at ^TokenSet other))
|
||||||
(-deref [_] {:id id
|
(= tokens (.-tokens ^TokenSet other))))
|
||||||
:name name
|
|
||||||
:description description
|
#?@(:cljs [cljs.core/IEquiv
|
||||||
:modified-at modified-at
|
(-equiv [this other] (.equals ^TokenSet this other))])
|
||||||
:tokens tokens})])
|
|
||||||
|
cp/Datafiable
|
||||||
|
(datafy [_]
|
||||||
|
{:id id
|
||||||
|
:name name
|
||||||
|
:description description
|
||||||
|
:modified-at modified-at
|
||||||
|
:tokens tokens})
|
||||||
|
|
||||||
#?@(:cljs [cljs.core/IEncodeJS
|
|
||||||
(-clj->js [_] (js-obj "id" (clj->js id)
|
|
||||||
"name" (clj->js name)
|
|
||||||
"description" (clj->js description)
|
|
||||||
"modified-at" (clj->js modified-at)
|
|
||||||
"tokens" (clj->js tokens)))])
|
|
||||||
INamedItem
|
INamedItem
|
||||||
(get-name [_]
|
(get-name [_]
|
||||||
name)
|
name)
|
||||||
@@ -266,6 +300,33 @@
|
|||||||
(get-tokens-map [_]
|
(get-tokens-map [_]
|
||||||
tokens))
|
tokens))
|
||||||
|
|
||||||
|
(defmethod pp/simple-dispatch TokenSet [^TokenSet obj]
|
||||||
|
(.write *out* "#penpot/token-set ")
|
||||||
|
(pp/pprint-newline :miser)
|
||||||
|
(pp/pprint (datafy obj)))
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
|
(do
|
||||||
|
(defmethod print-method TokenSet
|
||||||
|
[^TokenSet this ^java.io.Writer w]
|
||||||
|
(.write w "#penpot/token-set ")
|
||||||
|
(print-method (datafy this) w))
|
||||||
|
|
||||||
|
(defmethod print-dup TokenSet
|
||||||
|
[^TokenSet this ^java.io.Writer w]
|
||||||
|
(print-method this w)))
|
||||||
|
|
||||||
|
:cljs
|
||||||
|
(extend-type TokenSet
|
||||||
|
cljs.core/IPrintWithWriter
|
||||||
|
(-pr-writer [this writer opts]
|
||||||
|
(-write writer "#penpot/token-set ")
|
||||||
|
(-pr-writer (datafy this) writer opts))
|
||||||
|
|
||||||
|
cljs.core/IEncodeJS
|
||||||
|
(-clj->js [this]
|
||||||
|
(clj->js (datafy this)))))
|
||||||
|
|
||||||
(defn token-set?
|
(defn token-set?
|
||||||
[o]
|
[o]
|
||||||
(instance? TokenSet o))
|
(instance? TokenSet o))
|
||||||
@@ -528,6 +589,9 @@
|
|||||||
(hidden-theme? [_] "if a theme is the (from the user ui) hidden temporary theme"))
|
(hidden-theme? [_] "if a theme is the (from the user ui) hidden temporary theme"))
|
||||||
|
|
||||||
(defrecord TokenTheme [id name group description is-source external-id modified-at sets]
|
(defrecord TokenTheme [id name group description is-source external-id modified-at sets]
|
||||||
|
cp/Datafiable
|
||||||
|
(datafy [this] (into {} this))
|
||||||
|
|
||||||
INamedItem
|
INamedItem
|
||||||
(get-name [_]
|
(get-name [_]
|
||||||
name)
|
name)
|
||||||
@@ -594,6 +658,34 @@
|
|||||||
(hidden-theme? [this]
|
(hidden-theme? [this]
|
||||||
(theme-matches-group-name this hidden-theme-group hidden-theme-name)))
|
(theme-matches-group-name this hidden-theme-group hidden-theme-name)))
|
||||||
|
|
||||||
|
(defmethod pp/simple-dispatch TokenTheme
|
||||||
|
[^TokenTheme obj]
|
||||||
|
(.write *out* "#penpot/token-theme ")
|
||||||
|
(pp/pprint-newline :miser)
|
||||||
|
(pp/pprint (datafy obj)))
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
|
(do
|
||||||
|
(defmethod print-method TokenTheme
|
||||||
|
[^TokenTheme this ^java.io.Writer w]
|
||||||
|
(.write w "#penpot/token-theme ")
|
||||||
|
(print-method (datafy this) w))
|
||||||
|
|
||||||
|
(defmethod print-dup TokenTheme
|
||||||
|
[^TokenTheme this ^java.io.Writer w]
|
||||||
|
(print-method this w)))
|
||||||
|
|
||||||
|
:cljs
|
||||||
|
(extend-type TokenTheme
|
||||||
|
cljs.core/IPrintWithWriter
|
||||||
|
(-pr-writer [this writer opts]
|
||||||
|
(-write writer "#penpot/token-theme ")
|
||||||
|
(-pr-writer (datafy this) writer opts))
|
||||||
|
|
||||||
|
cljs.core/IEncodeJS
|
||||||
|
(-clj->js [this]
|
||||||
|
(clj->js (datafy this)))))
|
||||||
|
|
||||||
(defn token-theme?
|
(defn token-theme?
|
||||||
[o]
|
[o]
|
||||||
(instance? TokenTheme o))
|
(instance? TokenTheme o))
|
||||||
@@ -832,26 +924,12 @@ Will return a value that matches this schema:
|
|||||||
|
|
||||||
(deftype TokensLib [sets themes active-themes]
|
(deftype TokensLib [sets themes active-themes]
|
||||||
;; This is to convert the TokensLib to a plain map, for debugging or unit tests.
|
;; This is to convert the TokensLib to a plain map, for debugging or unit tests.
|
||||||
protocols/Datafiable
|
cp/Datafiable
|
||||||
(datafy [_]
|
(datafy [_]
|
||||||
{:sets (d/update-vals sets deref)
|
{:sets sets
|
||||||
:themes themes
|
:themes themes
|
||||||
:active-themes active-themes})
|
:active-themes active-themes})
|
||||||
|
|
||||||
;; TODO: this is used in serialization, but there should be a better way to do it
|
|
||||||
#?@(:clj [clojure.lang.IDeref
|
|
||||||
(deref [_] {:sets sets
|
|
||||||
:themes themes
|
|
||||||
:active-themes active-themes})]
|
|
||||||
:cljs [cljs.core/IDeref
|
|
||||||
(-deref [_] {:sets sets
|
|
||||||
:themes themes
|
|
||||||
:active-themes active-themes})])
|
|
||||||
|
|
||||||
#?@(:cljs [cljs.core/IEncodeJS
|
|
||||||
(-clj->js [_] (js-obj "sets" (clj->js sets)
|
|
||||||
"themes" (clj->js themes)
|
|
||||||
"active-themes" (clj->js active-themes)))])
|
|
||||||
#?@(:clj
|
#?@(:clj
|
||||||
[json/JSONWriter
|
[json/JSONWriter
|
||||||
(-write [this writter options] (json/-write (export-dtcg-json this) writter options))])
|
(-write [this writter options] (json/-write (export-dtcg-json this) writter options))])
|
||||||
@@ -1228,6 +1306,33 @@ Will return a value that matches this schema:
|
|||||||
(valid-token-themes? themes)
|
(valid-token-themes? themes)
|
||||||
(valid-active-token-themes? active-themes))))
|
(valid-active-token-themes? active-themes))))
|
||||||
|
|
||||||
|
(defmethod pp/simple-dispatch TokensLib
|
||||||
|
[^TokensLib obj]
|
||||||
|
(.write *out* "#penpot/token-lib ")
|
||||||
|
(pp/pprint-newline :miser)
|
||||||
|
(pp/pprint (export-dtcg-json obj)))
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
|
(do
|
||||||
|
(defmethod print-method TokensLib
|
||||||
|
[^TokensLib obj ^java.io.Writer w]
|
||||||
|
(.write w "#penpot/token-lib ")
|
||||||
|
(print-method (export-dtcg-json obj) w))
|
||||||
|
|
||||||
|
(defmethod print-dup TokensLib
|
||||||
|
[^TokensLib obj ^java.io.Writer w]
|
||||||
|
(print-method obj w)))
|
||||||
|
|
||||||
|
:cljs
|
||||||
|
(extend-type TokensLib
|
||||||
|
cljs.core/IPrintWithWriter
|
||||||
|
(-pr-writer [this writer opts]
|
||||||
|
(-write writer "#penpot/token-lib ")
|
||||||
|
(-pr-writer (export-dtcg-json this) writer opts))
|
||||||
|
|
||||||
|
cljs.core/IEncodeJS
|
||||||
|
(-clj->js [this] (clj->js (datafy this)))))
|
||||||
|
|
||||||
(defn get-hidden-theme
|
(defn get-hidden-theme
|
||||||
[tokens-lib]
|
[tokens-lib]
|
||||||
(get-theme tokens-lib hidden-theme-group hidden-theme-name))
|
(get-theme tokens-lib hidden-theme-group hidden-theme-name))
|
||||||
@@ -1448,7 +1553,7 @@ Will return a value that matches this schema:
|
|||||||
(assert (= (get-json-format decoded-json-tokens) :json-format/legacy) "expected a legacy format for `decoded-json-tokens`")
|
(assert (= (get-json-format decoded-json-tokens) :json-format/legacy) "expected a legacy format for `decoded-json-tokens`")
|
||||||
(parse-single-set-dtcg-json set-name (legacy-json->dtcg-json decoded-json-tokens)))
|
(parse-single-set-dtcg-json set-name (legacy-json->dtcg-json decoded-json-tokens)))
|
||||||
|
|
||||||
(defn- parse-multi-set-dtcg-json
|
(defn parse-multi-set-dtcg-json
|
||||||
"Parse a decoded json file with multi sets in DTCG format into a TokensLib."
|
"Parse a decoded json file with multi sets in DTCG format into a TokensLib."
|
||||||
[decoded-json]
|
[decoded-json]
|
||||||
(assert (map? decoded-json) "expected a plain clojure map for `decoded-json`")
|
(assert (map? decoded-json) "expected a plain clojure map for `decoded-json`")
|
||||||
@@ -1680,44 +1785,26 @@ Will return a value that matches this schema:
|
|||||||
(t/add-handlers!
|
(t/add-handlers!
|
||||||
{:id "penpot/tokens-lib"
|
{:id "penpot/tokens-lib"
|
||||||
:class TokensLib
|
:class TokensLib
|
||||||
:wfn deref
|
:wfn datafy
|
||||||
:rfn #(make-tokens-lib %)}
|
:rfn #(make-tokens-lib %)}
|
||||||
|
|
||||||
{:id "penpot/token-set"
|
{:id "penpot/token-set"
|
||||||
:class TokenSet
|
:class TokenSet
|
||||||
:wfn deref
|
:wfn datafy
|
||||||
:rfn #(make-token-set %)}
|
:rfn #(make-token-set %)}
|
||||||
|
|
||||||
{:id "penpot/token-theme"
|
{:id "penpot/token-theme"
|
||||||
:class TokenTheme
|
:class TokenTheme
|
||||||
:wfn #(into {} %)
|
:wfn datafy
|
||||||
:rfn #(map->TokenTheme %)}
|
:rfn #(map->TokenTheme %)}
|
||||||
|
|
||||||
{:id "penpot/token"
|
{:id "penpot/token"
|
||||||
:class Token
|
:class Token
|
||||||
:wfn #(into {} %)
|
:wfn datafy
|
||||||
:rfn #(map->Token %)})
|
:rfn #(map->Token %)})
|
||||||
|
|
||||||
;; === Serialization handlers for database (fressian)
|
;; === Serialization handlers for database (fressian)
|
||||||
|
|
||||||
#?(:clj
|
|
||||||
(defn- read-tokens-lib-v1-0
|
|
||||||
"Reads the first version of tokens lib, now completly obsolete"
|
|
||||||
[r]
|
|
||||||
(let [;; Migrate sets tree without prefix to new format
|
|
||||||
prev-sets (->> (fres/read-object! r)
|
|
||||||
(tree-seq d/ordered-map? vals)
|
|
||||||
(filter (partial instance? TokenSet)))
|
|
||||||
|
|
||||||
sets (-> (reduce add-set (make-tokens-lib) prev-sets)
|
|
||||||
(deref)
|
|
||||||
(:sets))
|
|
||||||
|
|
||||||
_set-groups (fres/read-object! r)
|
|
||||||
themes (fres/read-object! r)
|
|
||||||
active-themes (fres/read-object! r)]
|
|
||||||
(->TokensLib sets themes active-themes))))
|
|
||||||
|
|
||||||
#?(:clj
|
#?(:clj
|
||||||
(defn- read-tokens-lib-v1-1
|
(defn- read-tokens-lib-v1-1
|
||||||
"Reads the tokens lib data structure and ensures that hidden
|
"Reads the tokens lib data structure and ensures that hidden
|
||||||
@@ -1851,7 +1938,7 @@ Will return a value that matches this schema:
|
|||||||
:class TokenSet
|
:class TokenSet
|
||||||
:wfn (fn [n w o]
|
:wfn (fn [n w o]
|
||||||
(fres/write-tag! w n 1)
|
(fres/write-tag! w n 1)
|
||||||
(fres/write-object! w (into {} (deref o))))
|
(fres/write-object! w (datafy o)))
|
||||||
:rfn (fn [r]
|
:rfn (fn [r]
|
||||||
(let [obj (fres/read-object! r)]
|
(let [obj (fres/read-object! r)]
|
||||||
(make-token-set obj)))}
|
(make-token-set obj)))}
|
||||||
@@ -1865,10 +1952,6 @@ Will return a value that matches this schema:
|
|||||||
(let [obj (fres/read-object! r)]
|
(let [obj (fres/read-object! r)]
|
||||||
(make-token-theme obj)))}
|
(make-token-theme obj)))}
|
||||||
|
|
||||||
;; LEGACY TOKENS LIB READERS (with migrations)
|
|
||||||
{:name "penpot/tokens-lib/v1"
|
|
||||||
:rfn read-tokens-lib-v1-0}
|
|
||||||
|
|
||||||
{:name "penpot/tokens-lib/v1.1"
|
{:name "penpot/tokens-lib/v1.1"
|
||||||
:rfn read-tokens-lib-v1-1}
|
:rfn read-tokens-lib-v1-1}
|
||||||
|
|
||||||
|
|||||||
@@ -1408,7 +1408,7 @@
|
|||||||
|
|
||||||
#?(:clj
|
#?(:clj
|
||||||
(t/deftest export-parse-dtcg-json
|
(t/deftest export-parse-dtcg-json
|
||||||
(with-redefs [ct/now (constantly #inst "2024-10-16T12:01:20.257840055-00:00")
|
(with-redefs [ct/now (constantly (ct/inst "2024-10-16T12:01:20.257840055-00:00"))
|
||||||
uuid/next (constantly uuid/zero)]
|
uuid/next (constantly uuid/zero)]
|
||||||
(let [tokens-lib (-> (ctob/make-tokens-lib)
|
(let [tokens-lib (-> (ctob/make-tokens-lib)
|
||||||
(ctob/add-set (ctob/make-token-set :name "core"
|
(ctob/add-set (ctob/make-token-set :name "core"
|
||||||
|
|||||||
Reference in New Issue
Block a user