mirror of
https://github.com/penpot/penpot.git
synced 2025-02-08 08:09:14 -05:00
Merge pull request #262 from tokens-studio/refactor-types-1
🔧 Add tokens-lib custom type
This commit is contained in:
commit
6f37a43be1
20 changed files with 937 additions and 173 deletions
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
(ns user
|
(ns user
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
|
[app.common.fressian :as fres]
|
||||||
[app.common.pprint :as pp]
|
[app.common.pprint :as pp]
|
||||||
[app.common.schema :as sm]
|
[app.common.schema :as sm]
|
||||||
[app.common.schema.desc-js-like :as smdj]
|
[app.common.schema.desc-js-like :as smdj]
|
||||||
|
|
|
@ -44,8 +44,8 @@
|
||||||
|
|
||||||
(defn ordered-map
|
(defn ordered-map
|
||||||
([] lkm/empty-linked-map)
|
([] lkm/empty-linked-map)
|
||||||
([a] (conj lkm/empty-linked-map a))
|
([k a] (assoc lkm/empty-linked-map k a))
|
||||||
([a & xs] (apply conj lkm/empty-linked-map a xs)))
|
([k a & xs] (apply assoc lkm/empty-linked-map k a xs)))
|
||||||
|
|
||||||
(defn ordered-set?
|
(defn ordered-set?
|
||||||
[o]
|
[o]
|
||||||
|
@ -564,6 +564,41 @@
|
||||||
new-elems
|
new-elems
|
||||||
(remove p? after))))
|
(remove p? after))))
|
||||||
|
|
||||||
|
(defn addm-at-index
|
||||||
|
"Insert an element in an ordered map at an arbitrary index"
|
||||||
|
[coll index key element]
|
||||||
|
(assert (ordered-map? coll))
|
||||||
|
(-> (ordered-map)
|
||||||
|
(into (take index coll))
|
||||||
|
(assoc key element)
|
||||||
|
(into (drop index coll))))
|
||||||
|
|
||||||
|
(defn insertm-at-index
|
||||||
|
"Insert a map {k v} of elements in an ordered map at an arbitrary index"
|
||||||
|
[coll index new-elems]
|
||||||
|
(assert (ordered-map? coll))
|
||||||
|
(-> (ordered-map)
|
||||||
|
(into (take index coll))
|
||||||
|
(into new-elems)
|
||||||
|
(into (drop index coll))))
|
||||||
|
|
||||||
|
(defn adds-at-index
|
||||||
|
"Insert an element in an ordered set at an arbitrary index"
|
||||||
|
[coll index element]
|
||||||
|
(assert (ordered-set? coll))
|
||||||
|
(-> (ordered-set)
|
||||||
|
(into (take index coll))
|
||||||
|
(conj element)
|
||||||
|
(into (drop index coll))))
|
||||||
|
|
||||||
|
(defn inserts-at-index
|
||||||
|
"Insert a list of elements in an ordered set at an arbitrary index"
|
||||||
|
[coll index new-elems]
|
||||||
|
(assert (ordered-set? coll))
|
||||||
|
(-> (ordered-set)
|
||||||
|
(into (take index coll))
|
||||||
|
(into new-elems)
|
||||||
|
(into (drop index coll))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Data Parsing / Conversion
|
;; Data Parsing / Conversion
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
[app.common.types.shape-tree :as ctst]
|
[app.common.types.shape-tree :as ctst]
|
||||||
[app.common.types.token :as cto]
|
[app.common.types.token :as cto]
|
||||||
[app.common.types.token-theme :as ctot]
|
[app.common.types.token-theme :as ctot]
|
||||||
|
[app.common.types.tokens-lib :as ctob]
|
||||||
[app.common.types.tokens-list :as ctol]
|
[app.common.types.tokens-list :as ctol]
|
||||||
[app.common.types.tokens-theme-list :as ctotl]
|
[app.common.types.tokens-theme-list :as ctotl]
|
||||||
[app.common.types.typographies-list :as ctyl]
|
[app.common.types.typographies-list :as ctyl]
|
||||||
|
@ -289,28 +290,37 @@
|
||||||
[:map {:title "ModTokenSetChange"}
|
[:map {:title "ModTokenSetChange"}
|
||||||
[:type [:= :mod-token-set]]
|
[:type [:= :mod-token-set]]
|
||||||
[:id ::sm/uuid]
|
[:id ::sm/uuid]
|
||||||
|
[:name :string]
|
||||||
[:token-set ::ctot/token-set]]]
|
[:token-set ::ctot/token-set]]]
|
||||||
|
|
||||||
[:del-token-set
|
[:del-token-set
|
||||||
[:map {:title "DelTokenSetChange"}
|
[:map {:title "DelTokenSetChange"}
|
||||||
[:type [:= :del-token-set]]
|
[:type [:= :del-token-set]]
|
||||||
[:id ::sm/uuid]]]
|
[:id ::sm/uuid]
|
||||||
|
[:name :string]]]
|
||||||
|
|
||||||
[:add-token
|
[:add-token
|
||||||
[:map {:title "AddTokenChange"}
|
[:map {:title "AddTokenChange"}
|
||||||
[:type [:= :add-token]]
|
[:type [:= :add-token]]
|
||||||
|
[:set-id ::sm/uuid]
|
||||||
|
[:set-name :string]
|
||||||
[:token ::cto/token]]]
|
[:token ::cto/token]]]
|
||||||
|
|
||||||
[:mod-token
|
[:mod-token
|
||||||
[:map {:title "ModTokenChange"}
|
[:map {:title "ModTokenChange"}
|
||||||
[:type [:= :mod-token]]
|
[:type [:= :mod-token]]
|
||||||
|
[:set-id ::sm/uuid]
|
||||||
|
[:set-name :string]
|
||||||
[:id ::sm/uuid]
|
[:id ::sm/uuid]
|
||||||
|
[:name :string]
|
||||||
[:token ::cto/token]]]
|
[:token ::cto/token]]]
|
||||||
|
|
||||||
[:del-token
|
[:del-token
|
||||||
[:map {:title "DelTokenChange"}
|
[:map {:title "DelTokenChange"}
|
||||||
[:type [:= :del-token]]
|
[:type [:= :del-token]]
|
||||||
[:id ::sm/uuid]]]]])
|
[:set-name :string]
|
||||||
|
[:id ::sm/uuid]
|
||||||
|
[:name :string]]]]])
|
||||||
|
|
||||||
(sm/register! ::changes
|
(sm/register! ::changes
|
||||||
[:sequential {:gen/max 2} ::change])
|
[:sequential {:gen/max 2} ::change])
|
||||||
|
@ -780,16 +790,37 @@
|
||||||
;; -- Tokens
|
;; -- Tokens
|
||||||
|
|
||||||
(defmethod process-change :add-token
|
(defmethod process-change :add-token
|
||||||
[data {:keys [token]}]
|
[data {:keys [set-id set-name token]}]
|
||||||
(ctol/add-token data token))
|
(-> data
|
||||||
|
(ctol/add-token set-id token)
|
||||||
|
(update :tokens-lib
|
||||||
|
#(-> %
|
||||||
|
(ctob/ensure-tokens-lib)
|
||||||
|
(ctob/add-token-in-set set-name (ctob/make-token token))))))
|
||||||
|
|
||||||
(defmethod process-change :mod-token
|
(defmethod process-change :mod-token
|
||||||
[data {:keys [id token]}]
|
[data {:keys [set-name id name token]}]
|
||||||
(ctol/update-token data id merge token))
|
(-> data
|
||||||
|
(ctol/update-token id merge token)
|
||||||
|
(update :tokens-lib
|
||||||
|
#(-> %
|
||||||
|
(ctob/ensure-tokens-lib)
|
||||||
|
(ctob/update-token-in-set
|
||||||
|
set-name
|
||||||
|
name
|
||||||
|
(fn [old-token]
|
||||||
|
(ctob/make-token (merge old-token token))))))))
|
||||||
|
|
||||||
(defmethod process-change :del-token
|
(defmethod process-change :del-token
|
||||||
[data {:keys [id]}]
|
[data {:keys [set-name id name]}]
|
||||||
(ctol/delete-token data id))
|
(-> data
|
||||||
|
(ctol/delete-token id)
|
||||||
|
(update :tokens-lib
|
||||||
|
#(-> %
|
||||||
|
(ctob/ensure-tokens-lib)
|
||||||
|
(ctob/delete-token-from-set
|
||||||
|
set-name
|
||||||
|
name)))))
|
||||||
|
|
||||||
(defmethod process-change :add-temporary-token-theme
|
(defmethod process-change :add-temporary-token-theme
|
||||||
[data {:keys [token-theme]}]
|
[data {:keys [token-theme]}]
|
||||||
|
@ -817,15 +848,32 @@
|
||||||
|
|
||||||
(defmethod process-change :add-token-set
|
(defmethod process-change :add-token-set
|
||||||
[data {:keys [token-set]}]
|
[data {:keys [token-set]}]
|
||||||
(ctotl/add-token-set data token-set))
|
(-> data
|
||||||
|
(ctotl/add-token-set token-set)
|
||||||
|
(update :tokens-lib
|
||||||
|
#(-> %
|
||||||
|
(ctob/ensure-tokens-lib)
|
||||||
|
(ctob/add-set (ctob/make-token-set token-set))))))
|
||||||
|
|
||||||
(defmethod process-change :mod-token-set
|
(defmethod process-change :mod-token-set
|
||||||
[data {:keys [id token-set]}]
|
[data {:keys [id name token-set]}]
|
||||||
(ctotl/update-token-set data id merge token-set))
|
(-> data
|
||||||
|
(ctotl/update-token-set id merge token-set)
|
||||||
|
(update :tokens-lib
|
||||||
|
#(-> %
|
||||||
|
(ctob/ensure-tokens-lib)
|
||||||
|
(ctob/update-set name (fn [prev-set]
|
||||||
|
(merge prev-set
|
||||||
|
(dissoc token-set :tokens))))))))
|
||||||
|
|
||||||
(defmethod process-change :del-token-set
|
(defmethod process-change :del-token-set
|
||||||
[data {:keys [id]}]
|
[data {:keys [id name]}]
|
||||||
(ctotl/delete-token-set data id))
|
(-> data
|
||||||
|
(ctotl/delete-token-set id)
|
||||||
|
(update :tokens-lib
|
||||||
|
#(-> %
|
||||||
|
(ctob/ensure-tokens-lib)
|
||||||
|
(ctob/delete-set name)))))
|
||||||
|
|
||||||
;; === Operations
|
;; === Operations
|
||||||
(defmethod process-operation :set
|
(defmethod process-operation :set
|
||||||
|
@ -980,5 +1028,3 @@
|
||||||
(defmethod frames-changed :default
|
(defmethod frames-changed :default
|
||||||
[_ _]
|
[_ _]
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -737,48 +737,48 @@
|
||||||
[changes token-set]
|
[changes token-set]
|
||||||
(-> changes
|
(-> changes
|
||||||
(update :redo-changes conj {:type :add-token-set :token-set token-set})
|
(update :redo-changes conj {:type :add-token-set :token-set token-set})
|
||||||
(update :undo-changes conj {:type :del-token-set :id (:id token-set)})
|
(update :undo-changes conj {:type :del-token-set :id (:id token-set) :name (:name token-set)})
|
||||||
(apply-changes-local)))
|
(apply-changes-local)))
|
||||||
|
|
||||||
(defn update-token-set
|
(defn update-token-set
|
||||||
[changes token-set prev-token-set]
|
[changes token-set prev-token-set]
|
||||||
(-> changes
|
(-> changes
|
||||||
(update :redo-changes conj {:type :mod-token-set :id (:id token-set) :token-set token-set})
|
(update :redo-changes conj {:type :mod-token-set :id (:id token-set) :name (:name prev-token-set) :token-set token-set})
|
||||||
(update :undo-changes conj {:type :mod-token-set :id (:id token-set) :token-set (or prev-token-set token-set)})
|
(update :undo-changes conj {:type :mod-token-set :id (:id token-set) :name (:name prev-token-set) :token-set (or prev-token-set token-set)})
|
||||||
(apply-changes-local)))
|
(apply-changes-local)))
|
||||||
|
|
||||||
(defn delete-token-set
|
(defn delete-token-set
|
||||||
[changes token-set-id]
|
[changes token-set-id token-set-name]
|
||||||
(assert-library! changes)
|
(assert-library! changes)
|
||||||
(let [library-data (::library-data (meta changes))
|
(let [library-data (::library-data (meta changes))
|
||||||
prev-token-set (get-in library-data [:token-sets-index token-set-id])]
|
prev-token-set (get-in library-data [:token-sets-index token-set-id])]
|
||||||
(-> changes
|
(-> changes
|
||||||
(update :redo-changes conj {:type :del-token-set :id token-set-id})
|
(update :redo-changes conj {:type :del-token-set :id token-set-id :name token-set-name})
|
||||||
(update :undo-changes conj {:type :add-token-set :token-set prev-token-set})
|
(update :undo-changes conj {:type :add-token-set :token-set prev-token-set})
|
||||||
(apply-changes-local))))
|
(apply-changes-local))))
|
||||||
|
|
||||||
(defn add-token
|
(defn add-token
|
||||||
[changes token]
|
[changes set-id set-name token]
|
||||||
(-> changes
|
(-> changes
|
||||||
(update :redo-changes conj {:type :add-token :token token})
|
(update :redo-changes conj {:type :add-token :set-id set-id :set-name set-name :token token})
|
||||||
(update :undo-changes conj {:type :del-token :id (:id token)})
|
(update :undo-changes conj {:type :del-token :set-name set-name :id (:id token) :name (:name token)})
|
||||||
(apply-changes-local)))
|
(apply-changes-local)))
|
||||||
|
|
||||||
(defn update-token
|
(defn update-token
|
||||||
[changes {:keys [id] :as token} prev-token]
|
[changes set-id set-name {:keys [id name] :as token} {prev-name :name :as prev-token}]
|
||||||
(-> changes
|
(-> changes
|
||||||
(update :redo-changes conj {:type :mod-token :id id :token token})
|
(update :redo-changes conj {:type :mod-token :set-id set-id :set-name set-name :id id :name prev-name :token token})
|
||||||
(update :undo-changes conj {:type :mod-token :id id :token (or prev-token token)})
|
(update :undo-changes conj {:type :mod-token :set-id set-id :set-name set-name :id id :name name :token (or prev-token token)})
|
||||||
(apply-changes-local)))
|
(apply-changes-local)))
|
||||||
|
|
||||||
(defn delete-token
|
(defn delete-token
|
||||||
[changes token-id]
|
[changes set-name token-id token-name]
|
||||||
(assert-library! changes)
|
(assert-library! changes)
|
||||||
(let [library-data (::library-data (meta changes))
|
(let [library-data (::library-data (meta changes))
|
||||||
prev-token (get-in library-data [:tokens token-id])]
|
prev-token (get-in library-data [:tokens token-id])]
|
||||||
(-> changes
|
(-> changes
|
||||||
(update :redo-changes conj {:type :del-token :id token-id})
|
(update :redo-changes conj {:type :del-token :set-name set-name :id token-id :name token-name})
|
||||||
(update :undo-changes conj {:type :add-token :token prev-token})
|
(update :undo-changes conj {:type :add-token :set-id uuid/zero :set-name set-name :token prev-token})
|
||||||
(apply-changes-local))))
|
(apply-changes-local))))
|
||||||
|
|
||||||
(defn add-component
|
(defn add-component
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
java.time.Instant
|
java.time.Instant
|
||||||
java.time.OffsetDateTime
|
java.time.OffsetDateTime
|
||||||
java.util.List
|
java.util.List
|
||||||
|
linked.map.LinkedMap
|
||||||
org.fressian.Reader
|
org.fressian.Reader
|
||||||
org.fressian.StreamingWriter
|
org.fressian.StreamingWriter
|
||||||
org.fressian.Writer
|
org.fressian.Writer
|
||||||
|
@ -109,6 +110,13 @@
|
||||||
(clojure.lang.PersistentArrayMap. (.toArray kvs))
|
(clojure.lang.PersistentArrayMap. (.toArray kvs))
|
||||||
(clojure.lang.PersistentHashMap/create (seq kvs)))))
|
(clojure.lang.PersistentHashMap/create (seq kvs)))))
|
||||||
|
|
||||||
|
(defn read-ordered-map
|
||||||
|
[^Reader rdr]
|
||||||
|
(let [kvs ^java.util.List (read-object! rdr)]
|
||||||
|
(reduce #(assoc %1 (first %2) (second %2))
|
||||||
|
(d/ordered-map)
|
||||||
|
(partition-all 2 (seq kvs)))))
|
||||||
|
|
||||||
(def ^:dynamic *write-handler-lookup* nil)
|
(def ^:dynamic *write-handler-lookup* nil)
|
||||||
(def ^:dynamic *read-handler-lookup* nil)
|
(def ^:dynamic *read-handler-lookup* nil)
|
||||||
|
|
||||||
|
@ -225,6 +233,11 @@
|
||||||
:wfn write-map-like
|
:wfn write-map-like
|
||||||
:rfn read-map-like}
|
:rfn read-map-like}
|
||||||
|
|
||||||
|
{:name "linked/map"
|
||||||
|
:class LinkedMap
|
||||||
|
:wfn write-map-like
|
||||||
|
:rfn read-ordered-map}
|
||||||
|
|
||||||
{:name "clj/keyword"
|
{:name "clj/keyword"
|
||||||
:class clojure.lang.Keyword
|
:class clojure.lang.Keyword
|
||||||
:wfn write-named
|
:wfn write-named
|
||||||
|
|
|
@ -308,7 +308,6 @@
|
||||||
::explain explain}))))
|
::explain explain}))))
|
||||||
true)))
|
true)))
|
||||||
|
|
||||||
|
|
||||||
(defn fast-validate!
|
(defn fast-validate!
|
||||||
"A fast path for validation process, assumes the ILazySchema protocol
|
"A fast path for validation process, assumes the ILazySchema protocol
|
||||||
implemented on the provided `s` schema. Sould not be used directly."
|
implemented on the provided `s` schema. Sould not be used directly."
|
||||||
|
|
|
@ -26,11 +26,18 @@
|
||||||
#?(:clj (Instant/now)
|
#?(:clj (Instant/now)
|
||||||
:cljs (.local ^js DateTime)))
|
:cljs (.local ^js DateTime)))
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
|
(defn is-after?
|
||||||
|
[one other]
|
||||||
|
(.isAfter one other)))
|
||||||
|
|
||||||
(defn instant
|
(defn instant
|
||||||
[s]
|
[s]
|
||||||
#?(:clj (Instant/ofEpochMilli s)
|
#?(:clj (Instant/ofEpochMilli s)
|
||||||
:cljs (.fromMillis ^js DateTime s #js {:zone "local" :setZone false})))
|
:cljs (.fromMillis ^js DateTime s #js {:zone "local" :setZone false})))
|
||||||
|
|
||||||
|
;; To check for valid date time we can just use the core inst? function
|
||||||
|
|
||||||
#?(:cljs
|
#?(:cljs
|
||||||
(extend-protocol IComparable
|
(extend-protocol IComparable
|
||||||
DateTime
|
DateTime
|
||||||
|
@ -45,7 +52,6 @@
|
||||||
0
|
0
|
||||||
(if (< (inst-ms it) (inst-ms other)) -1 1)))))
|
(if (< (inst-ms it) (inst-ms other)) -1 1)))))
|
||||||
|
|
||||||
|
|
||||||
#?(:cljs
|
#?(:cljs
|
||||||
(extend-type DateTime
|
(extend-type DateTime
|
||||||
cljs.core/IEquiv
|
cljs.core/IEquiv
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
[app.common.uri :as uri]
|
[app.common.uri :as uri]
|
||||||
[cognitect.transit :as t]
|
[cognitect.transit :as t]
|
||||||
[lambdaisland.uri :as luri]
|
[lambdaisland.uri :as luri]
|
||||||
[linked.core :as lk]
|
[linked.map :as lkm]
|
||||||
[linked.set :as lks])
|
[linked.set :as lks])
|
||||||
#?(:clj
|
#?(:clj
|
||||||
(:import
|
(:import
|
||||||
|
@ -24,6 +24,7 @@
|
||||||
java.time.Instant
|
java.time.Instant
|
||||||
java.time.OffsetDateTime
|
java.time.OffsetDateTime
|
||||||
lambdaisland.uri.URI
|
lambdaisland.uri.URI
|
||||||
|
linked.map.LinkedMap
|
||||||
linked.set.LinkedSet)))
|
linked.set.LinkedSet)))
|
||||||
|
|
||||||
(def write-handlers (atom nil))
|
(def write-handlers (atom nil))
|
||||||
|
@ -118,10 +119,15 @@
|
||||||
{:id "u"
|
{:id "u"
|
||||||
:rfn parse-uuid})
|
:rfn parse-uuid})
|
||||||
|
|
||||||
|
{:id "ordered-map"
|
||||||
|
:class #?(:clj LinkedMap :cljs lkm/LinkedMap)
|
||||||
|
:wfn vec
|
||||||
|
:rfn #(into lkm/empty-linked-map %)}
|
||||||
|
|
||||||
{:id "ordered-set"
|
{:id "ordered-set"
|
||||||
:class #?(:clj LinkedSet :cljs lks/LinkedSet)
|
:class #?(:clj LinkedSet :cljs lks/LinkedSet)
|
||||||
:wfn vec
|
:wfn vec
|
||||||
:rfn #(into (lk/set) %)}
|
:rfn #(into lks/empty-linked-set %)}
|
||||||
|
|
||||||
{:id "duration"
|
{:id "duration"
|
||||||
:class #?(:clj Duration :cljs lxn/Duration)
|
:class #?(:clj Duration :cljs lxn/Duration)
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
[app.common.types.shape-tree :as ctst]
|
[app.common.types.shape-tree :as ctst]
|
||||||
[app.common.types.token :as cto]
|
[app.common.types.token :as cto]
|
||||||
[app.common.types.token-theme :as ctt]
|
[app.common.types.token-theme :as ctt]
|
||||||
|
[app.common.types.tokens-lib :as ctl]
|
||||||
[app.common.types.typographies-list :as ctyl]
|
[app.common.types.typographies-list :as ctyl]
|
||||||
[app.common.types.typography :as cty]
|
[app.common.types.typography :as cty]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
|
@ -78,7 +79,8 @@
|
||||||
[:token-sets-index {:optional true}
|
[:token-sets-index {:optional true}
|
||||||
[:map-of {:gen/max 10} ::sm/uuid ::ctt/token-set]]
|
[:map-of {:gen/max 10} ::sm/uuid ::ctt/token-set]]
|
||||||
[:tokens {:optional true}
|
[:tokens {:optional true}
|
||||||
[:map-of {:gen/max 100} ::sm/uuid ::cto/token]]])
|
[:map-of {:gen/max 100} ::sm/uuid ::cto/token]]
|
||||||
|
[:tokens-lib {:optional true} ::ctl/tokens-lib]])
|
||||||
|
|
||||||
(def check-file-data!
|
(def check-file-data!
|
||||||
(sm/check-fn ::data))
|
(sm/check-fn ::data))
|
||||||
|
|
|
@ -47,8 +47,16 @@
|
||||||
:string
|
:string
|
||||||
:typography})
|
:typography})
|
||||||
|
|
||||||
|
(defn valid-token-type?
|
||||||
|
[t]
|
||||||
|
(token-types t))
|
||||||
|
|
||||||
(def token-name-ref :string)
|
(def token-name-ref :string)
|
||||||
|
|
||||||
|
(defn valid-token-name-ref?
|
||||||
|
[n]
|
||||||
|
(string? n))
|
||||||
|
|
||||||
(sm/register! ::token
|
(sm/register! ::token
|
||||||
[:map {:title "Token"}
|
[:map {:title "Token"}
|
||||||
[:id ::sm/uuid]
|
[:id ::sm/uuid]
|
||||||
|
|
319
common/src/app/common/types/tokens_lib.cljc
Normal file
319
common/src/app/common/types/tokens_lib.cljc
Normal file
|
@ -0,0 +1,319 @@
|
||||||
|
;; 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) KALEIDOS INC
|
||||||
|
|
||||||
|
(ns app.common.types.tokens-lib
|
||||||
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.schema :as sm]
|
||||||
|
[app.common.time :as dt]
|
||||||
|
[app.common.transit :as t]
|
||||||
|
[app.common.types.token :as cto]
|
||||||
|
#?(:clj [app.common.fressian :as fres])))
|
||||||
|
|
||||||
|
;; #?(:clj (set! *warn-on-reflection* true))
|
||||||
|
|
||||||
|
;; === Token
|
||||||
|
|
||||||
|
(defrecord Token [name type value description modified-at])
|
||||||
|
|
||||||
|
(def schema:token
|
||||||
|
[:and
|
||||||
|
[:map {:title "Token"}
|
||||||
|
[:name cto/token-name-ref] ;; not necessary to have uuid
|
||||||
|
[:type [::sm/one-of cto/token-types]]
|
||||||
|
[:value :any]
|
||||||
|
[:description [:maybe :string]] ;; defrecord always have the attributes, even with nil value
|
||||||
|
[:modified-at ::sm/inst]]
|
||||||
|
[:fn (partial instance? Token)]])
|
||||||
|
|
||||||
|
(sm/register! ::token schema:token)
|
||||||
|
|
||||||
|
(def valid-token?
|
||||||
|
(sm/validator schema:token))
|
||||||
|
|
||||||
|
(def check-token!
|
||||||
|
(sm/check-fn ::token))
|
||||||
|
|
||||||
|
(defn make-token
|
||||||
|
[& {:keys [] :as params}]
|
||||||
|
(let [params (-> params
|
||||||
|
(dissoc :id) ;; we will remove this when old data structures are removed
|
||||||
|
(update :modified-at #(or % (dt/now))))
|
||||||
|
token (map->Token params)]
|
||||||
|
|
||||||
|
(dm/assert!
|
||||||
|
"expected valid token"
|
||||||
|
(check-token! token))
|
||||||
|
|
||||||
|
token))
|
||||||
|
|
||||||
|
;; === Token Set
|
||||||
|
|
||||||
|
(defprotocol ITokenSet
|
||||||
|
(add-token [_ token] "add a token at the end of the list")
|
||||||
|
(update-token [_ token-name f] "update a token in the list")
|
||||||
|
(delete-token [_ token-name] "delete a token from the list"))
|
||||||
|
|
||||||
|
(defrecord TokenSet [name description modified-at tokens]
|
||||||
|
ITokenSet
|
||||||
|
(add-token [_ token]
|
||||||
|
(dm/assert! "expected valid token" (check-token! token))
|
||||||
|
(TokenSet. name
|
||||||
|
description
|
||||||
|
(dt/now)
|
||||||
|
(assoc tokens (:name token) token)))
|
||||||
|
|
||||||
|
(update-token [this token-name f]
|
||||||
|
(if-let [token (get tokens token-name)]
|
||||||
|
(let [token' (-> (make-token (f token))
|
||||||
|
(assoc :modified-at (dt/now)))]
|
||||||
|
(check-token! token')
|
||||||
|
(TokenSet. name
|
||||||
|
description
|
||||||
|
(dt/now)
|
||||||
|
(if (= (:name token) (:name token'))
|
||||||
|
(assoc tokens (:name token') token')
|
||||||
|
(let [index (d/index-of (keys tokens) (:name token))]
|
||||||
|
(-> tokens
|
||||||
|
(dissoc (:name token))
|
||||||
|
(d/addm-at-index index (:name token') token'))))))
|
||||||
|
this))
|
||||||
|
|
||||||
|
(delete-token [_ token-name]
|
||||||
|
(TokenSet. name
|
||||||
|
description
|
||||||
|
(dt/now)
|
||||||
|
(dissoc tokens token-name))))
|
||||||
|
|
||||||
|
(def schema:token-set
|
||||||
|
[:and [:map {:title "TokenSet"}
|
||||||
|
[:name :string]
|
||||||
|
[:description [:maybe :string]]
|
||||||
|
[:modified-at ::sm/inst]
|
||||||
|
[:tokens [:map-of {:gen/max 5} :string ::token]]]
|
||||||
|
[:fn (partial instance? TokenSet)]])
|
||||||
|
|
||||||
|
(sm/register! ::token-set schema:token-set)
|
||||||
|
|
||||||
|
(def valid-token-set?
|
||||||
|
(sm/validator schema:token-set))
|
||||||
|
|
||||||
|
(def check-token-set!
|
||||||
|
(sm/check-fn ::token-set))
|
||||||
|
|
||||||
|
(defn make-token-set
|
||||||
|
[& {:keys [] :as params}]
|
||||||
|
(let [params (-> params
|
||||||
|
(dissoc :id)
|
||||||
|
(update :modified-at #(or % (dt/now)))
|
||||||
|
(update :tokens #(into (d/ordered-map) %)))
|
||||||
|
token-set (map->TokenSet params)]
|
||||||
|
|
||||||
|
(dm/assert!
|
||||||
|
"expected valid token set"
|
||||||
|
(check-token-set! token-set))
|
||||||
|
|
||||||
|
token-set))
|
||||||
|
|
||||||
|
;; === TokenSets (collection)
|
||||||
|
|
||||||
|
(defprotocol ITokenSets
|
||||||
|
(add-set [_ token-set] "add a set to the library, at the end")
|
||||||
|
(update-set [_ set-name f] "modify a set in the ilbrary")
|
||||||
|
(delete-set [_ set-name] "delete a set in the library")
|
||||||
|
(set-count [_] "get the total number if sets in the library")
|
||||||
|
(get-sets [_] "get an ordered sequence of all sets in the library")
|
||||||
|
(get-set [_ set-name] "get one set looking for name")
|
||||||
|
(validate [_]))
|
||||||
|
|
||||||
|
(def schema:token-sets
|
||||||
|
[:and
|
||||||
|
[:map-of {:title "TokenSets"}
|
||||||
|
:string ::token-set]
|
||||||
|
[:fn d/ordered-map?]])
|
||||||
|
|
||||||
|
(sm/register! ::token-sets schema:token-sets)
|
||||||
|
|
||||||
|
(def valid-token-sets?
|
||||||
|
(sm/validator schema:token-sets))
|
||||||
|
|
||||||
|
(def check-token-sets!
|
||||||
|
(sm/check-fn ::token-sets))
|
||||||
|
|
||||||
|
;; === TokenThemes (collection)
|
||||||
|
|
||||||
|
(def valid-token-themes?
|
||||||
|
(constantly true))
|
||||||
|
|
||||||
|
;; === Tokens Lib
|
||||||
|
|
||||||
|
(defprotocol ITokensLib
|
||||||
|
"A library of tokens, sets and themes."
|
||||||
|
(add-token-in-set [_ set-name token] "add token to a set")
|
||||||
|
(update-token-in-set [_ set-name token-name f] "update a token in a set")
|
||||||
|
(delete-token-from-set [_ set-name token-name] "delete a token from a set"))
|
||||||
|
|
||||||
|
(deftype TokensLib [sets themes]
|
||||||
|
;; NOTE: This is only for debug purposes, pending to properly
|
||||||
|
;; implement the toString and alternative printing.
|
||||||
|
#?@(:clj [clojure.lang.IDeref
|
||||||
|
(deref [_] {:sets sets :themes themes})]
|
||||||
|
:cljs [cljs.core/IDeref
|
||||||
|
(-deref [_] {:sets sets :themes themes})])
|
||||||
|
|
||||||
|
#?@(:cljs [cljs.core/IEncodeJS
|
||||||
|
(-clj->js [_] (js-obj "sets" (clj->js sets)
|
||||||
|
"themes" (clj->js themes)))])
|
||||||
|
|
||||||
|
ITokenSets
|
||||||
|
(add-set [_ token-set]
|
||||||
|
(dm/assert! "expected valid token set" (check-token-set! token-set))
|
||||||
|
(TokensLib. (assoc sets (:name token-set) token-set)
|
||||||
|
themes))
|
||||||
|
|
||||||
|
(update-set [this set-name f]
|
||||||
|
(if-let [set (get sets set-name)]
|
||||||
|
(let [set' (-> (make-token-set (f set))
|
||||||
|
(assoc :modified-at (dt/now)))]
|
||||||
|
(check-token-set! set')
|
||||||
|
(TokensLib. (if (= (:name set) (:name set'))
|
||||||
|
(assoc sets (:name set') set')
|
||||||
|
(let [index (d/index-of (keys sets) (:name set))]
|
||||||
|
(-> sets
|
||||||
|
(dissoc (:name set))
|
||||||
|
(d/addm-at-index index (:name set') set'))))
|
||||||
|
themes))
|
||||||
|
this))
|
||||||
|
|
||||||
|
(delete-set [_ set-name]
|
||||||
|
(TokensLib. (dissoc sets set-name)
|
||||||
|
themes))
|
||||||
|
|
||||||
|
(validate [_]
|
||||||
|
(and (valid-token-sets? sets)
|
||||||
|
(valid-token-themes? themes)))
|
||||||
|
|
||||||
|
(set-count [_]
|
||||||
|
(count sets))
|
||||||
|
|
||||||
|
(get-sets [_]
|
||||||
|
(vals sets))
|
||||||
|
|
||||||
|
(get-set [_ set-name]
|
||||||
|
(get sets set-name))
|
||||||
|
|
||||||
|
ITokensLib
|
||||||
|
(add-token-in-set [this set-name token]
|
||||||
|
(dm/assert! "expected valid token instance" (check-token! token))
|
||||||
|
(if (contains? sets set-name)
|
||||||
|
(TokensLib. (update sets set-name add-token token)
|
||||||
|
themes)
|
||||||
|
this))
|
||||||
|
|
||||||
|
(update-token-in-set [this set-name token-name f]
|
||||||
|
(if (contains? sets set-name)
|
||||||
|
(TokensLib. (update sets set-name
|
||||||
|
#(update-token % token-name f))
|
||||||
|
themes)
|
||||||
|
this))
|
||||||
|
|
||||||
|
(delete-token-from-set [this set-name token-name]
|
||||||
|
(if (contains? sets set-name)
|
||||||
|
(TokensLib. (update sets set-name
|
||||||
|
#(delete-token % token-name))
|
||||||
|
themes)
|
||||||
|
this)))
|
||||||
|
|
||||||
|
(defn valid-tokens-lib?
|
||||||
|
[o]
|
||||||
|
(and (instance? TokensLib o)
|
||||||
|
(validate o)))
|
||||||
|
|
||||||
|
(defn check-tokens-lib!
|
||||||
|
[lib]
|
||||||
|
(dm/assert!
|
||||||
|
"expected valid tokens lib"
|
||||||
|
(valid-tokens-lib? lib)))
|
||||||
|
|
||||||
|
(defn make-tokens-lib
|
||||||
|
"Create an empty or prepopulated tokens library."
|
||||||
|
([]
|
||||||
|
;; NOTE: is possible that ordered map is not the most apropriate
|
||||||
|
;; data structure and maybe we need a specific that allows us an
|
||||||
|
;; easy way to reorder it, or just store inside Tokens data
|
||||||
|
;; structure the data and the order separately as we already do
|
||||||
|
;; with pages and pages-index.
|
||||||
|
(make-tokens-lib :sets (d/ordered-map)
|
||||||
|
:themes (d/ordered-map)))
|
||||||
|
|
||||||
|
([& {:keys [sets themes]}]
|
||||||
|
(let [tokens-lib (TokensLib. sets themes)]
|
||||||
|
|
||||||
|
(dm/assert!
|
||||||
|
"expected valid tokens lib"
|
||||||
|
(valid-tokens-lib? tokens-lib))
|
||||||
|
|
||||||
|
tokens-lib)))
|
||||||
|
|
||||||
|
(defn ensure-tokens-lib
|
||||||
|
[tokens-lib]
|
||||||
|
(or tokens-lib (make-tokens-lib)))
|
||||||
|
|
||||||
|
(def type:tokens-lib
|
||||||
|
{:type ::tokens-lib
|
||||||
|
:pred valid-tokens-lib?})
|
||||||
|
|
||||||
|
(sm/register! ::tokens-lib type:tokens-lib)
|
||||||
|
|
||||||
|
;; === Serialization handlers for RPC API and database
|
||||||
|
|
||||||
|
(t/add-handlers!
|
||||||
|
{:id "penpot/tokens-lib"
|
||||||
|
:class TokensLib
|
||||||
|
:wfn deref
|
||||||
|
:rfn #(make-tokens-lib %)}
|
||||||
|
|
||||||
|
{:id "penpot/token-set"
|
||||||
|
:class TokenSet
|
||||||
|
:wfn #(into {} %)
|
||||||
|
:rfn #(make-token-set %)}
|
||||||
|
|
||||||
|
{:id "penpot/token"
|
||||||
|
:class Token
|
||||||
|
:wfn #(into {} %)
|
||||||
|
:rfn #(make-token %)})
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
|
(fres/add-handlers!
|
||||||
|
{:name "penpot/token/v1"
|
||||||
|
:class Token
|
||||||
|
:wfn (fn [n w o]
|
||||||
|
(fres/write-tag! w n 1)
|
||||||
|
(fres/write-object! w (into {} o)))
|
||||||
|
:rfn (fn [r]
|
||||||
|
(let [obj (fres/read-object! r)]
|
||||||
|
(map->Token obj)))}
|
||||||
|
|
||||||
|
{:name "penpot/token-set/v1"
|
||||||
|
:class TokenSet
|
||||||
|
:wfn (fn [n w o]
|
||||||
|
(fres/write-tag! w n 1)
|
||||||
|
(fres/write-object! w (into {} o)))
|
||||||
|
:rfn (fn [r]
|
||||||
|
(let [obj (fres/read-object! r)]
|
||||||
|
(map->TokenSet obj)))}
|
||||||
|
|
||||||
|
{:name "penpot/tokens-lib/v1"
|
||||||
|
:class TokensLib
|
||||||
|
:wfn (fn [n w o]
|
||||||
|
(fres/write-tag! w n 2)
|
||||||
|
(fres/write-object! w (.-sets o))
|
||||||
|
(fres/write-object! w (.-themes o)))
|
||||||
|
:rfn (fn [r]
|
||||||
|
(let [sets (fres/read-object! r)
|
||||||
|
themes (fres/read-object! r)]
|
||||||
|
(->TokensLib sets themes)))}))
|
|
@ -21,8 +21,12 @@
|
||||||
|
|
||||||
(defn add-token
|
(defn add-token
|
||||||
"Adds a new token to the file data, setting its `modified-at` timestamp."
|
"Adds a new token to the file data, setting its `modified-at` timestamp."
|
||||||
[file-data token]
|
[file-data token-set-id token]
|
||||||
(update file-data :tokens assoc (:id token) (touch token)))
|
(-> file-data
|
||||||
|
(update :tokens assoc (:id token) (touch token))
|
||||||
|
(d/update-in-when [:token-sets-index token-set-id] #(->
|
||||||
|
(update % :tokens conj (:id token))
|
||||||
|
(touch)))))
|
||||||
|
|
||||||
(defn get-token
|
(defn get-token
|
||||||
"Retrieves a token by its ID from the file data."
|
"Retrieves a token by its ID from the file data."
|
||||||
|
|
259
common/test/common_tests/types/tokens_lib_test.cljc
Normal file
259
common/test/common_tests/types/tokens_lib_test.cljc
Normal file
|
@ -0,0 +1,259 @@
|
||||||
|
;; 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) KALEIDOS INC
|
||||||
|
|
||||||
|
(ns common-tests.types.tokens-lib-test
|
||||||
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
|
[app.common.fressian :as fres]
|
||||||
|
[app.common.time :as dt]
|
||||||
|
[app.common.transit :as tr]
|
||||||
|
[app.common.types.tokens-lib :as ctob]
|
||||||
|
[clojure.test :as t]))
|
||||||
|
|
||||||
|
(t/deftest make-token
|
||||||
|
(let [now (dt/now)
|
||||||
|
token1 (ctob/make-token :name "test-token-1"
|
||||||
|
:type :boolean
|
||||||
|
:value true)
|
||||||
|
token2 (ctob/make-token :name "test-token-2"
|
||||||
|
:type :numeric
|
||||||
|
:value 66
|
||||||
|
:description "test description"
|
||||||
|
:modified-at now)]
|
||||||
|
|
||||||
|
(t/is (= (:name token1) "test-token-1"))
|
||||||
|
(t/is (= (:type token1) :boolean))
|
||||||
|
(t/is (= (:value token1) true))
|
||||||
|
(t/is (nil? (:description token1)))
|
||||||
|
(t/is (some? (:modified-at token1)))
|
||||||
|
(t/is (ctob/valid-token? token1))
|
||||||
|
|
||||||
|
(t/is (= (:name token2) "test-token-2"))
|
||||||
|
(t/is (= (:type token2) :numeric))
|
||||||
|
(t/is (= (:value token2) 66))
|
||||||
|
(t/is (= (:description token2) "test description"))
|
||||||
|
(t/is (= (:modified-at token2) now))
|
||||||
|
(t/is (ctob/valid-token? token2))))
|
||||||
|
|
||||||
|
(t/deftest invalid-tokens
|
||||||
|
(let [args {:name 777
|
||||||
|
:type :invalid}]
|
||||||
|
(t/is (thrown-with-msg? Exception #"expected valid token"
|
||||||
|
(apply ctob/make-token args)))
|
||||||
|
(t/is (false? (ctob/valid-token? {})))))
|
||||||
|
|
||||||
|
(t/deftest make-token-set
|
||||||
|
(let [now (dt/now)
|
||||||
|
token-set1 (ctob/make-token-set :name "test-token-set-1")
|
||||||
|
token-set2 (ctob/make-token-set :name "test-token-set-2"
|
||||||
|
:description "test description"
|
||||||
|
:modified-at now
|
||||||
|
:tokens [])]
|
||||||
|
|
||||||
|
(t/is (= (:name token-set1) "test-token-set-1"))
|
||||||
|
(t/is (nil? (:description token-set1)))
|
||||||
|
(t/is (some? (:modified-at token-set1)))
|
||||||
|
(t/is (empty? (:tokens token-set1)))
|
||||||
|
|
||||||
|
(t/is (= (:name token-set2) "test-token-set-2"))
|
||||||
|
(t/is (= (:description token-set2) "test description"))
|
||||||
|
(t/is (= (:modified-at token-set2) now))
|
||||||
|
(t/is (empty? (:tokens token-set2)))))
|
||||||
|
|
||||||
|
(t/deftest invalid-token-set
|
||||||
|
(let [args {:name 777
|
||||||
|
:description 999}]
|
||||||
|
(t/is (thrown-with-msg? Exception #"expected valid token set"
|
||||||
|
(apply ctob/make-token-set args)))))
|
||||||
|
|
||||||
|
(t/deftest make-tokens-lib
|
||||||
|
(let [tokens-lib (ctob/make-tokens-lib)]
|
||||||
|
(t/is (= (ctob/set-count tokens-lib) 0))))
|
||||||
|
|
||||||
|
(t/deftest add-token-set
|
||||||
|
(let [tokens-lib (ctob/make-tokens-lib)
|
||||||
|
token-set (ctob/make-token-set :name "test-token-set")
|
||||||
|
tokens-lib' (ctob/add-set tokens-lib token-set)
|
||||||
|
|
||||||
|
token-sets' (ctob/get-sets tokens-lib')
|
||||||
|
token-set' (ctob/get-set tokens-lib' "test-token-set")]
|
||||||
|
|
||||||
|
(t/is (= (ctob/set-count tokens-lib') 1))
|
||||||
|
(t/is (= (first token-sets') token-set))
|
||||||
|
(t/is (= token-set' token-set))))
|
||||||
|
|
||||||
|
(t/deftest update-token-set
|
||||||
|
(let [tokens-lib (-> (ctob/make-tokens-lib)
|
||||||
|
(ctob/add-set (ctob/make-token-set :name "test-token-set")))
|
||||||
|
|
||||||
|
tokens-lib' (-> tokens-lib
|
||||||
|
(ctob/update-set "test-token-set"
|
||||||
|
(fn [token-set]
|
||||||
|
(assoc token-set
|
||||||
|
:name "updated-name"
|
||||||
|
:description "some description")))
|
||||||
|
(ctob/update-set "not-existing-set"
|
||||||
|
(fn [token-set]
|
||||||
|
(assoc token-set
|
||||||
|
:name "no-effect"))))
|
||||||
|
|
||||||
|
token-set (ctob/get-set tokens-lib "test-token-set")
|
||||||
|
token-set' (ctob/get-set tokens-lib' "updated-name")]
|
||||||
|
|
||||||
|
(t/is (= (ctob/set-count tokens-lib') 1))
|
||||||
|
(t/is (= (:name token-set') "updated-name"))
|
||||||
|
(t/is (= (:description token-set') "some description"))
|
||||||
|
(t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set)))))
|
||||||
|
|
||||||
|
(t/deftest delete-token-set
|
||||||
|
(let [tokens-lib (-> (ctob/make-tokens-lib)
|
||||||
|
(ctob/add-set (ctob/make-token-set :name "test-token-set")))
|
||||||
|
|
||||||
|
tokens-lib' (-> tokens-lib
|
||||||
|
(ctob/delete-set "test-token-set")
|
||||||
|
(ctob/delete-set "not-existing-set"))
|
||||||
|
|
||||||
|
token-set' (ctob/get-set tokens-lib' "updated-name")]
|
||||||
|
|
||||||
|
(t/is (= (ctob/set-count tokens-lib') 0))
|
||||||
|
(t/is (nil? token-set'))))
|
||||||
|
|
||||||
|
(t/deftest add-token
|
||||||
|
(let [tokens-lib (-> (ctob/make-tokens-lib)
|
||||||
|
(ctob/add-set (ctob/make-token-set :name "test-token-set")))
|
||||||
|
token (ctob/make-token :name "test-token"
|
||||||
|
:type :boolean
|
||||||
|
:value true)
|
||||||
|
tokens-lib' (-> tokens-lib
|
||||||
|
(ctob/add-token-in-set "test-token-set" token)
|
||||||
|
(ctob/add-token-in-set "not-existing-set" token))
|
||||||
|
|
||||||
|
token-set (ctob/get-set tokens-lib "test-token-set")
|
||||||
|
token-set' (ctob/get-set tokens-lib' "test-token-set")
|
||||||
|
token' (get-in token-set' [:tokens "test-token"])]
|
||||||
|
|
||||||
|
(t/is (= (ctob/set-count tokens-lib') 1))
|
||||||
|
(t/is (= (count (:tokens token-set')) 1))
|
||||||
|
(t/is (= (:name token') "test-token"))
|
||||||
|
(t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set)))))
|
||||||
|
|
||||||
|
(t/deftest update-token
|
||||||
|
(let [tokens-lib (-> (ctob/make-tokens-lib)
|
||||||
|
(ctob/add-set (ctob/make-token-set :name "test-token-set"))
|
||||||
|
(ctob/add-token-in-set "test-token-set"
|
||||||
|
(ctob/make-token :name "test-token-1"
|
||||||
|
:type :boolean
|
||||||
|
:value true))
|
||||||
|
(ctob/add-token-in-set "test-token-set"
|
||||||
|
(ctob/make-token :name "test-token-2"
|
||||||
|
:type :boolean
|
||||||
|
:value true)))
|
||||||
|
|
||||||
|
tokens-lib' (-> tokens-lib
|
||||||
|
(ctob/update-token-in-set "test-token-set" "test-token-1"
|
||||||
|
(fn [token]
|
||||||
|
(assoc token
|
||||||
|
:description "some description"
|
||||||
|
:value false)))
|
||||||
|
(ctob/update-token-in-set "not-existing-set" "test-token-1"
|
||||||
|
(fn [token]
|
||||||
|
(assoc token
|
||||||
|
:name "no-effect")))
|
||||||
|
(ctob/update-token-in-set "test-token-set" "not-existing-token"
|
||||||
|
(fn [token]
|
||||||
|
(assoc token
|
||||||
|
:name "no-effect"))))
|
||||||
|
|
||||||
|
token-set (ctob/get-set tokens-lib "test-token-set")
|
||||||
|
token-set' (ctob/get-set tokens-lib' "test-token-set")
|
||||||
|
token (get-in token-set [:tokens "test-token-1"])
|
||||||
|
token' (get-in token-set' [:tokens "test-token-1"])]
|
||||||
|
|
||||||
|
(t/is (= (ctob/set-count tokens-lib') 1))
|
||||||
|
(t/is (= (count (:tokens token-set')) 2))
|
||||||
|
(t/is (= (d/index-of (keys (:tokens token-set')) "test-token-1") 0))
|
||||||
|
(t/is (= (:name token') "test-token-1"))
|
||||||
|
(t/is (= (:description token') "some description"))
|
||||||
|
(t/is (= (:value token') false))
|
||||||
|
(t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set)))
|
||||||
|
(t/is (dt/is-after? (:modified-at token') (:modified-at token)))))
|
||||||
|
|
||||||
|
(t/deftest rename-token
|
||||||
|
(let [tokens-lib (-> (ctob/make-tokens-lib)
|
||||||
|
(ctob/add-set (ctob/make-token-set :name "test-token-set"))
|
||||||
|
(ctob/add-token-in-set "test-token-set"
|
||||||
|
(ctob/make-token :name "test-token-1"
|
||||||
|
:type :boolean
|
||||||
|
:value true))
|
||||||
|
(ctob/add-token-in-set "test-token-set"
|
||||||
|
(ctob/make-token :name "test-token-2"
|
||||||
|
:type :boolean
|
||||||
|
:value true)))
|
||||||
|
|
||||||
|
tokens-lib' (-> tokens-lib
|
||||||
|
(ctob/update-token-in-set "test-token-set" "test-token-1"
|
||||||
|
(fn [token]
|
||||||
|
(assoc token
|
||||||
|
:name "updated-name"))))
|
||||||
|
|
||||||
|
token-set (ctob/get-set tokens-lib "test-token-set")
|
||||||
|
token-set' (ctob/get-set tokens-lib' "test-token-set")
|
||||||
|
token (get-in token-set [:tokens "test-token-1"])
|
||||||
|
token' (get-in token-set' [:tokens "updated-name"])]
|
||||||
|
|
||||||
|
(t/is (= (ctob/set-count tokens-lib') 1))
|
||||||
|
(t/is (= (count (:tokens token-set')) 2))
|
||||||
|
(t/is (= (d/index-of (keys (:tokens token-set')) "updated-name") 0))
|
||||||
|
(t/is (= (:name token') "updated-name"))
|
||||||
|
(t/is (= (:description token') nil))
|
||||||
|
(t/is (= (:value token') true))
|
||||||
|
(t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set)))
|
||||||
|
(t/is (dt/is-after? (:modified-at token') (:modified-at token)))))
|
||||||
|
|
||||||
|
(t/deftest delete-token
|
||||||
|
(let [tokens-lib (-> (ctob/make-tokens-lib)
|
||||||
|
(ctob/add-set (ctob/make-token-set :name "test-token-set"))
|
||||||
|
(ctob/add-token-in-set "test-token-set"
|
||||||
|
(ctob/make-token :name "test-token"
|
||||||
|
:type :boolean
|
||||||
|
:value true)))
|
||||||
|
tokens-lib' (-> tokens-lib
|
||||||
|
(ctob/delete-token-from-set "test-token-set" "test-token")
|
||||||
|
(ctob/delete-token-from-set "not-existing-set" "test-token")
|
||||||
|
(ctob/delete-token-from-set "test-set" "not-existing-token"))
|
||||||
|
|
||||||
|
token-set (ctob/get-set tokens-lib "test-token-set")
|
||||||
|
token-set' (ctob/get-set tokens-lib' "test-token-set")
|
||||||
|
token' (get-in token-set' [:tokens "test-token"])]
|
||||||
|
|
||||||
|
(t/is (= (ctob/set-count tokens-lib') 1))
|
||||||
|
(t/is (= (count (:tokens token-set')) 0))
|
||||||
|
(t/is (nil? token'))
|
||||||
|
(t/is (dt/is-after? (:modified-at token-set') (:modified-at token-set)))))
|
||||||
|
|
||||||
|
(t/deftest transit-serialization
|
||||||
|
(let [tokens-lib (-> (ctob/make-tokens-lib)
|
||||||
|
(ctob/add-set (ctob/make-token-set :name "test-token-set"))
|
||||||
|
(ctob/add-token-in-set "test-token-set" (ctob/make-token :name "test-token"
|
||||||
|
:type :boolean
|
||||||
|
:value true)))
|
||||||
|
encoded-str (tr/encode-str tokens-lib)
|
||||||
|
tokens-lib' (tr/decode-str encoded-str)]
|
||||||
|
|
||||||
|
(t/is (ctob/valid-tokens-lib? tokens-lib'))
|
||||||
|
(t/is (= (ctob/set-count tokens-lib') 1))))
|
||||||
|
|
||||||
|
(t/deftest fressian-serialization
|
||||||
|
(let [tokens-lib (-> (ctob/make-tokens-lib)
|
||||||
|
(ctob/add-set (ctob/make-token-set :name "test-token-set"))
|
||||||
|
(ctob/add-token-in-set "test-token-set" (ctob/make-token :name "test-token"
|
||||||
|
:type :boolean
|
||||||
|
:value true)))
|
||||||
|
encoded-blob (fres/encode tokens-lib)
|
||||||
|
tokens-lib' (fres/decode encoded-blob)]
|
||||||
|
|
||||||
|
(t/is (ctob/valid-tokens-lib? tokens-lib'))
|
||||||
|
(t/is (= (ctob/set-count tokens-lib') 1))))
|
|
@ -96,6 +96,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tokens-studio/sd-transforms": "^0.16.1",
|
"@tokens-studio/sd-transforms": "^0.16.1",
|
||||||
|
"bun": "^1.1.25",
|
||||||
"compression": "^1.7.4",
|
"compression": "^1.7.4",
|
||||||
"date-fns": "^3.6.0",
|
"date-fns": "^3.6.0",
|
||||||
"eventsource-parser": "^1.1.2",
|
"eventsource-parser": "^1.1.2",
|
||||||
|
|
|
@ -81,6 +81,11 @@
|
||||||
(let [workspace-data (deref refs/workspace-data)]
|
(let [workspace-data (deref refs/workspace-data)]
|
||||||
(get (:tokens workspace-data) id)))
|
(get (:tokens workspace-data) id)))
|
||||||
|
|
||||||
|
(defn get-token-set-data-from-token-set-id
|
||||||
|
[id]
|
||||||
|
(let [workspace-data (deref refs/workspace-data)]
|
||||||
|
(get (:token-sets-index workspace-data) id)))
|
||||||
|
|
||||||
(defn set-selected-token-set-id
|
(defn set-selected-token-set-id
|
||||||
[id]
|
[id]
|
||||||
(ptk/reify ::set-selected-token-set-id
|
(ptk/reify ::set-selected-token-set-id
|
||||||
|
@ -88,6 +93,10 @@
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(wtts/assoc-selected-token-set-id state id))))
|
(wtts/assoc-selected-token-set-id state id))))
|
||||||
|
|
||||||
|
(defn get-token-set-tokens
|
||||||
|
[token-set file]
|
||||||
|
(map #(get-in file [:tokens %]) (:tokens token-set)))
|
||||||
|
|
||||||
(defn create-token-theme [token-theme]
|
(defn create-token-theme [token-theme]
|
||||||
(let [new-token-theme (merge
|
(let [new-token-theme (merge
|
||||||
{:id (uuid/next)
|
{:id (uuid/next)
|
||||||
|
@ -120,7 +129,7 @@
|
||||||
(not theme-id) (-> changes
|
(not theme-id) (-> changes
|
||||||
(pcb/add-temporary-token-theme
|
(pcb/add-temporary-token-theme
|
||||||
{:id (uuid/next)
|
{:id (uuid/next)
|
||||||
:name ""
|
:name "Test theme"
|
||||||
:sets #{id}}))
|
:sets #{id}}))
|
||||||
new-set? (-> changes
|
new-set? (-> changes
|
||||||
(pcb/update-token-theme
|
(pcb/update-token-theme
|
||||||
|
@ -196,14 +205,14 @@
|
||||||
(dch/commit-changes changes)
|
(dch/commit-changes changes)
|
||||||
(wtu/update-workspace-tokens))))))
|
(wtu/update-workspace-tokens))))))
|
||||||
|
|
||||||
(defn delete-token-set [token-set-id]
|
(defn delete-token-set [token-set-id token-set-name]
|
||||||
(ptk/reify ::delete-token-set
|
(ptk/reify ::delete-token-set
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [data (get state :workspace-data)
|
(let [data (get state :workspace-data)
|
||||||
changes (-> (pcb/empty-changes it)
|
changes (-> (pcb/empty-changes it)
|
||||||
(pcb/with-library-data data)
|
(pcb/with-library-data data)
|
||||||
(pcb/delete-token-set token-set-id))]
|
(pcb/delete-token-set token-set-id token-set-name))]
|
||||||
(rx/of
|
(rx/of
|
||||||
(dch/commit-changes changes)
|
(dch/commit-changes changes)
|
||||||
(wtu/update-workspace-tokens))))))
|
(wtu/update-workspace-tokens))))))
|
||||||
|
@ -214,46 +223,44 @@
|
||||||
(ptk/reify ::update-create-token
|
(ptk/reify ::update-create-token
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [prev-token (get-token-data-from-token-id (:id token))
|
(let [token-set (wtts/get-selected-token-set state)
|
||||||
|
create-set? (not token-set)
|
||||||
|
token-set (or token-set
|
||||||
|
{:id (uuid/next)
|
||||||
|
:name "Global"
|
||||||
|
:tokens []})
|
||||||
|
|
||||||
|
changes (cond-> (pcb/empty-changes it)
|
||||||
|
create-set?
|
||||||
|
(pcb/add-token-set token-set))
|
||||||
|
|
||||||
|
prev-token-id (d/seek #(= % (:id token)) (:tokens token-set))
|
||||||
|
prev-token (get-token-data-from-token-id prev-token-id)
|
||||||
create-token? (not prev-token)
|
create-token? (not prev-token)
|
||||||
token-changes (if create-token?
|
|
||||||
(-> (pcb/empty-changes it)
|
changes (if create-token?
|
||||||
(pcb/add-token token))
|
(pcb/add-token changes (:id token-set) (:name token-set) token)
|
||||||
(-> (pcb/empty-changes it)
|
(pcb/update-token changes (:id token-set) (:name token-set) token prev-token))
|
||||||
(pcb/update-token token prev-token)))
|
|
||||||
token-set (wtts/get-selected-token-set state)
|
changes (-> changes
|
||||||
create-set? (not token-set)
|
|
||||||
new-token-set {:id (uuid/next)
|
|
||||||
:name "Global"
|
|
||||||
:tokens [(:id token)]}
|
|
||||||
selected-token-set-id (if create-set?
|
|
||||||
(:id new-token-set)
|
|
||||||
(:id token-set))
|
|
||||||
set-changes (cond
|
|
||||||
create-set? (-> token-changes
|
|
||||||
(pcb/add-token-set new-token-set))
|
|
||||||
:else (let [updated-token-set (if (contains? token-set (:id token))
|
|
||||||
token-set
|
|
||||||
(update token-set :tokens conj (:id token)))]
|
|
||||||
(-> token-changes
|
|
||||||
(pcb/update-token-set updated-token-set token-set))))
|
|
||||||
theme-changes (-> set-changes
|
|
||||||
(ensure-token-theme-changes state {:new-set? create-set?
|
(ensure-token-theme-changes state {:new-set? create-set?
|
||||||
:id selected-token-set-id}))]
|
:id (:id token-set)}))]
|
||||||
(rx/of
|
(rx/of
|
||||||
(set-selected-token-set-id selected-token-set-id)
|
(set-selected-token-set-id (:id token-set))
|
||||||
(dch/commit-changes theme-changes)))))))
|
(dch/commit-changes changes)))))))
|
||||||
|
|
||||||
(defn delete-token
|
(defn delete-token
|
||||||
[id]
|
[set-name id name]
|
||||||
|
(dm/assert! (string? set-name))
|
||||||
(dm/assert! (uuid? id))
|
(dm/assert! (uuid? id))
|
||||||
|
(dm/assert! (string? name))
|
||||||
(ptk/reify ::delete-token
|
(ptk/reify ::delete-token
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [data (get state :workspace-data)
|
(let [data (get state :workspace-data)
|
||||||
changes (-> (pcb/empty-changes it)
|
changes (-> (pcb/empty-changes it)
|
||||||
(pcb/with-library-data data)
|
(pcb/with-library-data data)
|
||||||
(pcb/delete-token id))]
|
(pcb/delete-token set-name id name))]
|
||||||
(rx/of (dch/commit-changes changes))))))
|
(rx/of (dch/commit-changes changes))))))
|
||||||
|
|
||||||
(defn duplicate-token
|
(defn duplicate-token
|
||||||
|
|
|
@ -201,10 +201,11 @@
|
||||||
(generic-attribute-actions #{:x} "X" (assoc context-data :on-update-shape wtch/update-shape-position))
|
(generic-attribute-actions #{:x} "X" (assoc context-data :on-update-shape wtch/update-shape-position))
|
||||||
(generic-attribute-actions #{:y} "Y" (assoc context-data :on-update-shape wtch/update-shape-position))))}))
|
(generic-attribute-actions #{:y} "Y" (assoc context-data :on-update-shape wtch/update-shape-position))))}))
|
||||||
|
|
||||||
(defn default-actions [{:keys [token]}]
|
(defn default-actions [{:keys [token selected-token-set-id]}]
|
||||||
(let [{:keys [modal]} (wtty/get-token-properties token)]
|
(let [{:keys [modal]} (wtty/get-token-properties token)
|
||||||
|
selected-token-set (dt/get-token-set-data-from-token-set-id selected-token-set-id)]
|
||||||
[{:title "Delete Token"
|
[{:title "Delete Token"
|
||||||
:action #(st/emit! (dt/delete-token (:id token)))}
|
:action #(st/emit! (dt/delete-token (:name selected-token-set) (:id token) (:name token)))}
|
||||||
{:title "Duplicate Token"
|
{:title "Duplicate Token"
|
||||||
:action #(st/emit! (dt/duplicate-token (:id token)))}
|
:action #(st/emit! (dt/duplicate-token (:id token)))}
|
||||||
{:title "Edit Token"
|
{:title "Edit Token"
|
||||||
|
@ -311,7 +312,8 @@
|
||||||
selected (mf/deref refs/selected-shapes)
|
selected (mf/deref refs/selected-shapes)
|
||||||
selected-shapes (into [] (keep (d/getf objects)) selected)
|
selected-shapes (into [] (keep (d/getf objects)) selected)
|
||||||
token-id (:token-id mdata)
|
token-id (:token-id mdata)
|
||||||
token (get (mf/deref refs/workspace-selected-token-set-tokens) token-id)]
|
token (get (mf/deref refs/workspace-selected-token-set-tokens) token-id)
|
||||||
|
selected-token-set-id (mf/deref refs/workspace-selected-token-set-id)]
|
||||||
(mf/use-effect
|
(mf/use-effect
|
||||||
(mf/deps mdata)
|
(mf/deps mdata)
|
||||||
(fn []
|
(fn []
|
||||||
|
@ -327,4 +329,5 @@
|
||||||
[:ul {:class (stl/css :context-list)}
|
[:ul {:class (stl/css :context-list)}
|
||||||
[:& menu-tree {:submenu-offset @width
|
[:& menu-tree {:submenu-offset @width
|
||||||
:token token
|
:token token
|
||||||
|
:selected-token-set-id selected-token-set-id
|
||||||
:selected-shapes selected-shapes}]])]]))
|
:selected-shapes selected-shapes}]])]]))
|
||||||
|
|
|
@ -26,9 +26,9 @@
|
||||||
(defn on-select-token-set-click [id]
|
(defn on-select-token-set-click [id]
|
||||||
(st/emit! (wdt/set-selected-token-set-id id)))
|
(st/emit! (wdt/set-selected-token-set-id id)))
|
||||||
|
|
||||||
(defn on-delete-token-set-click [id event]
|
(defn on-delete-token-set-click [id name event]
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(st/emit! (wdt/delete-token-set id)))
|
(st/emit! (wdt/delete-token-set id name)))
|
||||||
|
|
||||||
(defn on-update-token-set [token-set]
|
(defn on-update-token-set [token-set]
|
||||||
(st/emit! (wdt/update-token-set token-set)))
|
(st/emit! (wdt/update-token-set token-set)))
|
||||||
|
@ -115,7 +115,7 @@
|
||||||
[:*
|
[:*
|
||||||
[:div {:class (stl/css :set-name)} name]
|
[:div {:class (stl/css :set-name)} name]
|
||||||
[:div {:class (stl/css :delete-set)}
|
[:div {:class (stl/css :delete-set)}
|
||||||
[:button {:on-click #(on-delete-token-set-click id %)
|
[:button {:on-click #(on-delete-token-set-click id name %)
|
||||||
:type "button"}
|
:type "button"}
|
||||||
i/delete]]
|
i/delete]]
|
||||||
(if set?
|
(if set?
|
||||||
|
|
|
@ -13,106 +13,65 @@
|
||||||
|
|
||||||
(def token-types
|
(def token-types
|
||||||
(ordered-map
|
(ordered-map
|
||||||
[:border-radius
|
:border-radius
|
||||||
{:title "Border Radius"
|
{:title "Border Radius"
|
||||||
:attributes ctt/border-radius-keys
|
:attributes ctt/border-radius-keys
|
||||||
:on-update-shape wtch/update-shape-radius-all
|
:on-update-shape wtch/update-shape-radius-all
|
||||||
:modal {:key :tokens/border-radius
|
:modal {:key :tokens/border-radius
|
||||||
:fields [{:label "Border Radius"
|
:fields [{:label "Border Radius"
|
||||||
:key :border-radius}]}}]
|
:key :border-radius}]}}
|
||||||
[:stroke-width
|
:stroke-width
|
||||||
{:title "Stroke Width"
|
{:title "Stroke Width"
|
||||||
:attributes ctt/stroke-width-keys
|
:attributes ctt/stroke-width-keys
|
||||||
:on-update-shape wtch/update-stroke-width
|
:on-update-shape wtch/update-stroke-width
|
||||||
:modal {:key :tokens/stroke-width
|
:modal {:key :tokens/stroke-width
|
||||||
:fields [{:label "Stroke Width"
|
:fields [{:label "Stroke Width"
|
||||||
:key :stroke-width}]}}]
|
:key :stroke-width}]}}
|
||||||
|
|
||||||
[:sizing
|
:sizing
|
||||||
{:title "Sizing"
|
{:title "Sizing"
|
||||||
:attributes #{:width :height}
|
:attributes #{:width :height}
|
||||||
:all-attributes ctt/sizing-keys
|
:all-attributes ctt/sizing-keys
|
||||||
:on-update-shape wtch/update-shape-dimensions
|
:on-update-shape wtch/update-shape-dimensions
|
||||||
:modal {:key :tokens/sizing
|
:modal {:key :tokens/sizing
|
||||||
:fields [{:label "Sizing"
|
:fields [{:label "Sizing"
|
||||||
:key :sizing}]}}]
|
:key :sizing}]}}
|
||||||
[:dimensions
|
:dimensions
|
||||||
{:title "Dimensions"
|
{:title "Dimensions"
|
||||||
:attributes #{:width :height}
|
:attributes #{:width :height}
|
||||||
:all-attributes (set/union
|
:all-attributes (set/union
|
||||||
ctt/spacing-keys
|
ctt/spacing-keys
|
||||||
ctt/sizing-keys
|
ctt/sizing-keys
|
||||||
ctt/border-radius-keys
|
ctt/border-radius-keys
|
||||||
ctt/stroke-width-keys)
|
ctt/stroke-width-keys)
|
||||||
:on-update-shape wtch/update-shape-dimensions
|
:on-update-shape wtch/update-shape-dimensions
|
||||||
:modal {:key :tokens/dimensions
|
:modal {:key :tokens/dimensions
|
||||||
:fields [{:label "Dimensions"
|
:fields [{:label "Dimensions"
|
||||||
:key :dimensions}]}}]
|
:key :dimensions}]}}
|
||||||
|
|
||||||
[:opacity
|
:opacity
|
||||||
{:title "Opacity"
|
{:title "Opacity"
|
||||||
:attributes ctt/opacity-keys
|
:attributes ctt/opacity-keys
|
||||||
:on-update-shape wtch/update-opacity
|
:on-update-shape wtch/update-opacity
|
||||||
:modal {:key :tokens/opacity
|
:modal {:key :tokens/opacity
|
||||||
:fields [{:label "Opacity"
|
:fields [{:label "Opacity"
|
||||||
:key :opacity}]}}]
|
:key :opacity}]}}
|
||||||
|
|
||||||
[:rotation
|
:rotation
|
||||||
{:title "Rotation"
|
{:title "Rotation"
|
||||||
:attributes ctt/rotation-keys
|
:attributes ctt/rotation-keys
|
||||||
:on-update-shape wtch/update-rotation
|
:on-update-shape wtch/update-rotation
|
||||||
:modal {:key :tokens/rotation
|
:modal {:key :tokens/rotation
|
||||||
:fields [{:label "Rotation"
|
:fields [{:label "Rotation"
|
||||||
:key :rotation}]}}]
|
:key :rotation}]}}
|
||||||
[:spacing
|
:spacing
|
||||||
{:title "Spacing"
|
{:title "Spacing"
|
||||||
:attributes #{:column-gap :row-gap}
|
:attributes #{:column-gap :row-gap}
|
||||||
:all-attributes ctt/spacing-keys
|
:all-attributes ctt/spacing-keys
|
||||||
:on-update-shape wtch/update-layout-spacing
|
:on-update-shape wtch/update-layout-spacing
|
||||||
:modal {:key :tokens/spacing
|
:modal {:key :tokens/spacing
|
||||||
:fields [{:label "Spacing"
|
:fields [{:label "Spacing"
|
||||||
:key :spacing}]}}]
|
:key :spacing}]}}))
|
||||||
(comment
|
|
||||||
[:boolean
|
|
||||||
{:title "Boolean"
|
|
||||||
:modal {:key :tokens/boolean
|
|
||||||
:fields [{:label "Boolean"}]}}]
|
|
||||||
|
|
||||||
[:box-shadow
|
|
||||||
{:title "Box Shadow"
|
|
||||||
:modal {:key :tokens/box-shadow
|
|
||||||
:fields [{:label "Box shadows"
|
|
||||||
:key :box-shadow
|
|
||||||
:type :box-shadow}]}}]
|
|
||||||
|
|
||||||
[:numeric
|
|
||||||
{:title "Numeric"
|
|
||||||
:modal {:key :tokens/numeric
|
|
||||||
:fields [{:label "Numeric"
|
|
||||||
:key :numeric}]}}]
|
|
||||||
|
|
||||||
[:other
|
|
||||||
{:title "Other"
|
|
||||||
:modal {:key :tokens/other
|
|
||||||
:fields [{:label "Other"
|
|
||||||
:key :other}]}}]
|
|
||||||
[:string
|
|
||||||
{:title "String"
|
|
||||||
:modal {:key :tokens/string
|
|
||||||
:fields [{:label "String"
|
|
||||||
:key :string}]}}]
|
|
||||||
[:typography
|
|
||||||
{:title "Typography"
|
|
||||||
:modal {:key :tokens/typography
|
|
||||||
:fields [{:label "Font" :key :font-family}
|
|
||||||
{:label "Weight" :key :weight}
|
|
||||||
{:label "Font Size" :key :font-size}
|
|
||||||
{:label "Line Height" :key :line-height}
|
|
||||||
{:label "Letter Spacing" :key :letter-spacing}
|
|
||||||
{:label "Paragraph Spacing" :key :paragraph-spacing}
|
|
||||||
{:label "Paragraph Indent" :key :paragraph-indent}
|
|
||||||
{:label "Text Decoration" :key :text-decoration}
|
|
||||||
{:label "Text Case" :key :text-case}]}}])))
|
|
||||||
|
|
||||||
(defn get-token-properties [token]
|
(defn get-token-properties [token]
|
||||||
(get token-types (:type token)))
|
(get token-types (:type token)))
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
(ns token-tests.logic.token-actions-test
|
(ns token-tests.logic.token-actions-test
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.pprint :refer [pprint]]
|
||||||
[app.common.logging :as log]
|
[app.common.logging :as log]
|
||||||
[app.common.test-helpers.compositions :as ctho]
|
[app.common.test-helpers.compositions :as ctho]
|
||||||
[app.common.test-helpers.files :as cthf]
|
[app.common.test-helpers.files :as cthf]
|
||||||
|
|
|
@ -2427,6 +2427,62 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@oven/bun-darwin-aarch64@npm:1.1.25":
|
||||||
|
version: 1.1.25
|
||||||
|
resolution: "@oven/bun-darwin-aarch64@npm:1.1.25"
|
||||||
|
conditions: os=darwin & cpu=arm64
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@oven/bun-darwin-x64-baseline@npm:1.1.25":
|
||||||
|
version: 1.1.25
|
||||||
|
resolution: "@oven/bun-darwin-x64-baseline@npm:1.1.25"
|
||||||
|
conditions: os=darwin & cpu=x64
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@oven/bun-darwin-x64@npm:1.1.25":
|
||||||
|
version: 1.1.25
|
||||||
|
resolution: "@oven/bun-darwin-x64@npm:1.1.25"
|
||||||
|
conditions: os=darwin & cpu=x64
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@oven/bun-linux-aarch64@npm:1.1.25":
|
||||||
|
version: 1.1.25
|
||||||
|
resolution: "@oven/bun-linux-aarch64@npm:1.1.25"
|
||||||
|
conditions: os=linux & cpu=arm64
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@oven/bun-linux-x64-baseline@npm:1.1.25":
|
||||||
|
version: 1.1.25
|
||||||
|
resolution: "@oven/bun-linux-x64-baseline@npm:1.1.25"
|
||||||
|
conditions: os=linux & cpu=x64
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@oven/bun-linux-x64@npm:1.1.25":
|
||||||
|
version: 1.1.25
|
||||||
|
resolution: "@oven/bun-linux-x64@npm:1.1.25"
|
||||||
|
conditions: os=linux & cpu=x64
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@oven/bun-windows-x64-baseline@npm:1.1.25":
|
||||||
|
version: 1.1.25
|
||||||
|
resolution: "@oven/bun-windows-x64-baseline@npm:1.1.25"
|
||||||
|
conditions: os=win32 & cpu=x64
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@oven/bun-windows-x64@npm:1.1.25":
|
||||||
|
version: 1.1.25
|
||||||
|
resolution: "@oven/bun-windows-x64@npm:1.1.25"
|
||||||
|
conditions: os=win32 & cpu=x64
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@pkgjs/parseargs@npm:^0.11.0":
|
"@pkgjs/parseargs@npm:^0.11.0":
|
||||||
version: 0.11.0
|
version: 0.11.0
|
||||||
resolution: "@pkgjs/parseargs@npm:0.11.0"
|
resolution: "@pkgjs/parseargs@npm:0.11.0"
|
||||||
|
@ -4379,6 +4435,43 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"bun@npm:^1.1.25":
|
||||||
|
version: 1.1.25
|
||||||
|
resolution: "bun@npm:1.1.25"
|
||||||
|
dependencies:
|
||||||
|
"@oven/bun-darwin-aarch64": "npm:1.1.25"
|
||||||
|
"@oven/bun-darwin-x64": "npm:1.1.25"
|
||||||
|
"@oven/bun-darwin-x64-baseline": "npm:1.1.25"
|
||||||
|
"@oven/bun-linux-aarch64": "npm:1.1.25"
|
||||||
|
"@oven/bun-linux-x64": "npm:1.1.25"
|
||||||
|
"@oven/bun-linux-x64-baseline": "npm:1.1.25"
|
||||||
|
"@oven/bun-windows-x64": "npm:1.1.25"
|
||||||
|
"@oven/bun-windows-x64-baseline": "npm:1.1.25"
|
||||||
|
dependenciesMeta:
|
||||||
|
"@oven/bun-darwin-aarch64":
|
||||||
|
optional: true
|
||||||
|
"@oven/bun-darwin-x64":
|
||||||
|
optional: true
|
||||||
|
"@oven/bun-darwin-x64-baseline":
|
||||||
|
optional: true
|
||||||
|
"@oven/bun-linux-aarch64":
|
||||||
|
optional: true
|
||||||
|
"@oven/bun-linux-x64":
|
||||||
|
optional: true
|
||||||
|
"@oven/bun-linux-x64-baseline":
|
||||||
|
optional: true
|
||||||
|
"@oven/bun-windows-x64":
|
||||||
|
optional: true
|
||||||
|
"@oven/bun-windows-x64-baseline":
|
||||||
|
optional: true
|
||||||
|
bin:
|
||||||
|
bun: bin/bun.exe
|
||||||
|
bunx: bin/bun.exe
|
||||||
|
checksum: 10c0/ac0cec14aaaaae8b5b3818c6868dd417a60fb5d9c4230f5265c19c0367fd588ae9175ce0feac04db5b5684d624187c639fae1854ee2b52cdd2e2ae0a75a7dd9c
|
||||||
|
conditions: (os=darwin | os=linux | os=win32) & (cpu=arm64 | cpu=x64)
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"bytes@npm:3.0.0":
|
"bytes@npm:3.0.0":
|
||||||
version: 3.0.0
|
version: 3.0.0
|
||||||
resolution: "bytes@npm:3.0.0"
|
resolution: "bytes@npm:3.0.0"
|
||||||
|
@ -6819,6 +6912,7 @@ __metadata:
|
||||||
"@tokens-studio/sd-transforms": "npm:^0.16.1"
|
"@tokens-studio/sd-transforms": "npm:^0.16.1"
|
||||||
"@types/node": "npm:^20.11.20"
|
"@types/node": "npm:^20.11.20"
|
||||||
autoprefixer: "npm:^10.4.19"
|
autoprefixer: "npm:^10.4.19"
|
||||||
|
bun: "npm:^1.1.25"
|
||||||
compression: "npm:^1.7.4"
|
compression: "npm:^1.7.4"
|
||||||
concurrently: "npm:^8.2.2"
|
concurrently: "npm:^8.2.2"
|
||||||
date-fns: "npm:^3.6.0"
|
date-fns: "npm:^3.6.0"
|
||||||
|
|
Loading…
Add table
Reference in a new issue