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/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/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.types.token :as cto]
|
||||
[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.walk :as walk]
|
||||
[cuerdas.core :as str]))
|
||||
@@ -71,6 +73,9 @@
|
||||
;; === Token
|
||||
|
||||
(defrecord Token [id name type value description modified-at]
|
||||
cp/Datafiable
|
||||
(datafy [this] (into {} this))
|
||||
|
||||
INamedItem
|
||||
(get-name [_]
|
||||
name)
|
||||
@@ -87,6 +92,34 @@
|
||||
(set-description [this 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?
|
||||
[o]
|
||||
(instance? Token o))
|
||||
@@ -175,25 +208,26 @@
|
||||
(defrecord TokenSetLegacy [id name description modified-at tokens])
|
||||
|
||||
(deftype TokenSet [id name description modified-at tokens]
|
||||
#?@(:clj [clojure.lang.IDeref
|
||||
(deref [_] {:id id
|
||||
:name name
|
||||
:description description
|
||||
:modified-at modified-at
|
||||
:tokens tokens})]
|
||||
:cljs [cljs.core/IDeref
|
||||
(-deref [_] {:id id
|
||||
:name name
|
||||
:description description
|
||||
:modified-at modified-at
|
||||
:tokens tokens})])
|
||||
Object
|
||||
(equals [_ other]
|
||||
(and (instance? TokenSet other)
|
||||
(= id (.-id ^TokenSet other))
|
||||
(= name (.-name ^TokenSet other))
|
||||
(= description (.-description ^TokenSet other))
|
||||
(= modified-at (.-modified-at ^TokenSet other))
|
||||
(= tokens (.-tokens ^TokenSet other))))
|
||||
|
||||
#?@(:cljs [cljs.core/IEquiv
|
||||
(-equiv [this other] (.equals ^TokenSet this other))])
|
||||
|
||||
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
|
||||
(get-name [_]
|
||||
name)
|
||||
@@ -266,6 +300,33 @@
|
||||
(get-tokens-map [_]
|
||||
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?
|
||||
[o]
|
||||
(instance? TokenSet o))
|
||||
@@ -528,6 +589,9 @@
|
||||
(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]
|
||||
cp/Datafiable
|
||||
(datafy [this] (into {} this))
|
||||
|
||||
INamedItem
|
||||
(get-name [_]
|
||||
name)
|
||||
@@ -594,6 +658,34 @@
|
||||
(hidden-theme? [this]
|
||||
(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?
|
||||
[o]
|
||||
(instance? TokenTheme o))
|
||||
@@ -832,26 +924,12 @@ Will return a value that matches this schema:
|
||||
|
||||
(deftype TokensLib [sets themes active-themes]
|
||||
;; This is to convert the TokensLib to a plain map, for debugging or unit tests.
|
||||
protocols/Datafiable
|
||||
cp/Datafiable
|
||||
(datafy [_]
|
||||
{:sets (d/update-vals sets deref)
|
||||
{:sets sets
|
||||
:themes 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
|
||||
[json/JSONWriter
|
||||
(-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-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
|
||||
[tokens-lib]
|
||||
(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`")
|
||||
(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."
|
||||
[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!
|
||||
{:id "penpot/tokens-lib"
|
||||
:class TokensLib
|
||||
:wfn deref
|
||||
:wfn datafy
|
||||
:rfn #(make-tokens-lib %)}
|
||||
|
||||
{:id "penpot/token-set"
|
||||
:class TokenSet
|
||||
:wfn deref
|
||||
:wfn datafy
|
||||
:rfn #(make-token-set %)}
|
||||
|
||||
{:id "penpot/token-theme"
|
||||
:class TokenTheme
|
||||
:wfn #(into {} %)
|
||||
:wfn datafy
|
||||
:rfn #(map->TokenTheme %)}
|
||||
|
||||
{:id "penpot/token"
|
||||
:class Token
|
||||
:wfn #(into {} %)
|
||||
:wfn datafy
|
||||
:rfn #(map->Token %)})
|
||||
|
||||
;; === 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
|
||||
(defn- read-tokens-lib-v1-1
|
||||
"Reads the tokens lib data structure and ensures that hidden
|
||||
@@ -1851,7 +1938,7 @@ Will return a value that matches this schema:
|
||||
:class TokenSet
|
||||
:wfn (fn [n w o]
|
||||
(fres/write-tag! w n 1)
|
||||
(fres/write-object! w (into {} (deref o))))
|
||||
(fres/write-object! w (datafy o)))
|
||||
:rfn (fn [r]
|
||||
(let [obj (fres/read-object! r)]
|
||||
(make-token-set obj)))}
|
||||
@@ -1865,10 +1952,6 @@ Will return a value that matches this schema:
|
||||
(let [obj (fres/read-object! r)]
|
||||
(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"
|
||||
:rfn read-tokens-lib-v1-1}
|
||||
|
||||
|
||||
@@ -1408,7 +1408,7 @@
|
||||
|
||||
#?(:clj
|
||||
(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)]
|
||||
(let [tokens-lib (-> (ctob/make-tokens-lib)
|
||||
(ctob/add-set (ctob/make-token-set :name "core"
|
||||
|
||||
Reference in New Issue
Block a user