This commit is contained in:
Andrey Antukh
2025-08-19 14:09:07 +02:00
parent d46ad9d6f1
commit 04f573cb23
5 changed files with 232 additions and 133 deletions

View File

@@ -111,7 +111,7 @@
(defmethod visit :fn [_ _ _ _] "FN")
(defmethod visit :vector [_ _ children _]
(str "[" (last children) "]"))
(str "[" (str/trim (last children)) "]"))
(defn -tagged [children] (map (fn [[tag _ c]] (str c " (tag: " tag ")")) children))
@@ -137,8 +137,14 @@
(some? suffix)
(str suffix))))
(defmethod visit :map-of [_ _ children _]
(str "map[" (first children) "," (second children) "]"))
(defmethod visit :map-of
[_ schema children _]
(let [props (m/properties schema)
title (some->> (:title props) str/camel str/capital)]
(str (if title
(str "type " title ": ")
"")
"map[" (first children) "," (second children) "]")))
(defmethod visit :union [_ _ children _]
(str/join " | " children))
@@ -156,61 +162,123 @@
(or (:title props)
"*")))
(defn- format-map
[schema children]
(let [props (m/properties schema)
closed? (get props :closed)
title (some->> (:title props) str/camel str/capital)
level 0
optional (into #{} (comp (filter (m/-comp :optional second))
(map first))
children)
entries (->> children
(map (fn [[k _ s]]
;; NOTE: maybe we can detect multiple lines
;; and then just insert a break line
(str (pad " " level) (str/camel k)
(when (contains? optional k) "?")
": " (str/trim s))))
(str/join ",\n"))
header (cond-> (str "type " title)
closed? (str "!")
(some? title) (str " "))]
(str (pad header level) "{\n" entries "\n" (pad "}\n" level))))
(defmethod visit :map
[_ schema children {:keys [::level ::max-level] :as options}]
(let [props (m/properties schema)
closed? (:closed props)
title (some->> (:title props) str/camel str/capital)]
(let [props (m/properties schema)
closed? (get props :closed)
title (some->> (:title props) str/camel str/capital)
extracted? (get props ::extracted false)]
(if (>= level max-level)
(or (some-> title str)
"<untitled>")
(let [optional (into #{} (comp (filter (m/-comp :optional second))
(map first))
children)
entries (->> children
(map (fn [[k _ s]]
(str (pad " " level) (str/camel k)
(when (contains? optional k) "?")
": " s)))
(str/join ",\n"))
(if (= level 0)
(format-map schema children)
header (cond-> (str "type " title)
closed? (str "!")
(some? title) (str " "))]
(if title
(if extracted?
(format-map schema children)
(let [schema (mu/update-properties schema assoc ::extracted true)]
(swap! *definitions* conj (describe* schema options))
(pad title level)))
(format-map schema children)))))
(str (pad header level) "{\n" entries "\n" (pad "}\n" level))))))
(defn format-multi
[s children]
(let [props (m/properties s)
title (some-> (:title props) str/camel str/capital)
dispatcher (or (-> s m/properties :dispatch-description)
(-> s m/properties :dispatch))
(defmethod visit :multi
[_ s children {:keys [::level ::max-level] :as options}]
(let [props (m/properties s)
title (some-> (:title props) str/camel str/capital)]
(if (>= level max-level)
title
(let [dispatcher (or (-> s m/properties :dispatch-description)
(-> s m/properties :dispatch))
entries (->> children
(map (fn [[_ _ shape]]
(str shape)))
(str/join ",\n"))
prefix (apply str (take (inc level) (repeat " ")))
entries (->> children
(map (fn [[_ _ shape]]
(str prefix shape)))
(str/join ",\n"))
header (cond-> "multi"
header (cond-> "multi"
(some? title) (str " " title)
:always (str " [dispatch=" (d/name dispatcher) "]"))]
(str header " {\n" entries "\n" (pad "}" level))))))
(str header " {\n" entries "\n}")))
(defmethod visit :multi
[_ schema children {:keys [::level ::max-level] :as options}]
(let [props (m/properties schema)
title (some-> (:title props) str/camel str/capital)
extracted? (get props ::extracted false)]
(cond
(zero? level)
(format-multi schema children)
(and title extracted?)
(format-multi schema children)
(and title (not extracted?))
(let [schema (mu/update-properties schema assoc ::extracted true)]
(swap! *definitions* conj (describe* schema options))
(pad title level))
:else
(format-multi schema children))))
(defn- format-merge
[schema children]
(let [props (m/properties schema)
entries (->> children
(map (fn [shape]
(str shape)))
(str/join ",\n"))
title (some-> (:title props) str/camel str/capital)
header (str "merge type " title)]
(str header " {\n" entries "\n}")))
(defmethod visit :merge
[_ schema children _]
(let [entries (str/join ",\n" children)
props (m/properties schema)
title (or (some-> (:title props) str/camel str/capital)
"<untitled>")]
(str "merge type " title " { \n" entries "\n}\n")))
[_ schema children {:keys [::level ::max-level] :as options}]
(let [props (m/properties schema)
title (some-> (:title props) str/camel str/capital)
extracted? (get props ::extracted false)]
(cond
(zero? level)
(format-merge schema children)
(and title extracted?)
(format-merge schema children)
(and title (not extracted?))
(let [schema (mu/update-properties schema assoc ::extracted true)]
(swap! *definitions* conj (describe* schema options))
(pad title level))
:else
(format-merge schema children))))
(defmethod visit ::sm/one-of
[_ _ children _]
@@ -219,8 +287,21 @@
(map d/name)
(str/join "|")) ")")))
(defmethod visit :schema [_ schema children options]
(visit ::m/schema schema children options))
(defmethod visit :schema
[_ schema children options]
(let [props (m/properties schema)
title (some-> (:title props) str/camel str/capital)
extracted? (get props ::extracted false)]
(if title
(if extracted?
(str "type " title ": "
(visit ::m/schema schema children options))
(let [schema (mu/update-properties schema assoc ::extracted true)]
(swap! *definitions* conj (describe* schema options))
title))
(visit ::m/schema schema children options))))
(defmethod visit ::m/schema
[_ schema _ {:keys [::level ::limit ::max-level] :as options}]
@@ -239,9 +320,12 @@
(describe* schema' options)))
(and ref title)
(do
(when (<= limit max-level)
(swap! *definitions* conj (describe* schema' (assoc options ::base-limit limit))))
(let [options (-> options
(assoc ::base-level level)
)]
;; (when (<= limit max-level)
(swap! *definitions* conj (describe* schema' options))
title)
@@ -254,10 +338,11 @@
(describe* schema' (assoc options ::base-level level ::base-limit limit)))))
(defn describe* [s options]
(letfn [(walk-fn [schema path children {:keys [::base-level ::base-limit] :or {base-level 0 base-limit 0} :as options}]
(let [options (assoc options
::limit (+ base-limit (count path))
::level (+ base-level (count path)))]
(letfn [(walk-fn [schema path children {:keys [::base-level ::base-limit]
:or {base-level 0 base-limit 0} :as options}]
(let [options (-> options
(assoc ::limit (+ base-limit (count path)))
(assoc ::level (+ base-level (count path))))]
(visit (m/type schema) schema children options)))]
(m/walk s walk-fn options)))

View File

@@ -24,7 +24,7 @@
(def schema:plugin-data
(sm/register!
^{::sm/type ::plugin-data}
[:map-of {:gen/max 5}
[:map-of {:gen/max 5 :title "PluginsData"}
schema:keyword
[:map-of {:gen/max 5}
schema:string

View File

@@ -185,50 +185,50 @@
[:height ::sm/safe-number]])
(def schema:shape-generic-attrs
[:map {:title "ShapeAttrs"}
[:page-id {:optional true} ::sm/uuid]
[:component-id {:optional true} ::sm/uuid]
[:component-file {:optional true} ::sm/uuid]
[:component-root {:optional true} :boolean]
[:main-instance {:optional true} :boolean]
[:remote-synced {:optional true} :boolean]
[:shape-ref {:optional true} ::sm/uuid]
[:touched {:optional true} [:maybe [:set :keyword]]]
[:blocked {:optional true} :boolean]
[:collapsed {:optional true} :boolean]
[:locked {:optional true} :boolean]
[:hidden {:optional true} :boolean]
[:masked-group {:optional true} :boolean]
[:fills {:optional true}
[:vector {:gen/max 2} schema:fill]]
[:proportion {:optional true} ::sm/safe-number]
[:proportion-lock {:optional true} :boolean]
[:constraints-h {:optional true}
[::sm/one-of horizontal-constraint-types]]
[:constraints-v {:optional true}
[::sm/one-of vertical-constraint-types]]
[:fixed-scroll {:optional true} :boolean]
[:r1 {:optional true} ::sm/safe-number]
[:r2 {:optional true} ::sm/safe-number]
[:r3 {:optional true} ::sm/safe-number]
[:r4 {:optional true} ::sm/safe-number]
[:opacity {:optional true} ::sm/safe-number]
[:grids {:optional true}
[:vector {:gen/max 2} ::ctg/grid]]
[:exports {:optional true}
[:vector {:gen/max 2} ::ctse/export]]
[:strokes {:optional true}
[:vector {:gen/max 2} schema:stroke]]
[:blend-mode {:optional true}
[::sm/one-of blend-modes]]
[:map {:title "ShapeGenericAttrs"}
;; [:page-id {:optional true} ::sm/uuid]
;; [:component-id {:optional true} ::sm/uuid]
;; [:component-file {:optional true} ::sm/uuid]
;; [:component-root {:optional true} :boolean]
;; [:main-instance {:optional true} :boolean]
;; [:remote-synced {:optional true} :boolean]
;; [:shape-ref {:optional true} ::sm/uuid]
;; [:touched {:optional true} [:maybe [:set :keyword]]]
;; [:blocked {:optional true} :boolean]
;; [:collapsed {:optional true} :boolean]
;; [:locked {:optional true} :boolean]
;; [:hidden {:optional true} :boolean]
;; [:masked-group {:optional true} :boolean]
;; [:fills {:optional true}
;; [:vector {:gen/max 2} schema:fill]]
;; [:proportion {:optional true} ::sm/safe-number]
;; [:proportion-lock {:optional true} :boolean]
;; [:constraints-h {:optional true}
;; [::sm/one-of horizontal-constraint-types]]
;; [:constraints-v {:optional true}
;; [::sm/one-of vertical-constraint-types]]
;; [:fixed-scroll {:optional true} :boolean]
;; [:r1 {:optional true} ::sm/safe-number]
;; [:r2 {:optional true} ::sm/safe-number]
;; [:r3 {:optional true} ::sm/safe-number]
;; [:r4 {:optional true} ::sm/safe-number]
;; [:opacity {:optional true} ::sm/safe-number]
;; [:grids {:optional true}
;; [:vector {:gen/max 2} ::ctg/grid]]
;; [:exports {:optional true}
;; [:vector {:gen/max 2} ::ctse/export]]
;; [:strokes {:optional true}
;; [:vector {:gen/max 2} schema:stroke]]
;; [:blend-mode {:optional true}
;; [::sm/one-of blend-modes]]
[:interactions {:optional true}
[:vector {:gen/max 2} ::ctsi/interaction]]
[:shadow {:optional true}
[:vector {:gen/max 1} ctss/schema:shadow]]
[:blur {:optional true} ::ctsb/blur]
;; [:shadow {:optional true}
;; [:vector {:gen/max 1} ctss/schema:shadow]]
;; [:blur {:optional true} ::ctsb/blur]
[:grow-type {:optional true}
[::sm/one-of grow-types]]
[:applied-tokens {:optional true} cto/schema:applied-tokens]
;; [:applied-tokens {:optional true} cto/schema:applied-tokens]
[:plugin-data {:optional true} ::ctpg/plugin-data]])
(def schema:group-attrs
@@ -306,6 +306,15 @@
(merge attrs1 shape attrs2 attrs3)))))
(sg/fmap create-shape)))
(def kaka
[:merge {:title "BoolShape"}
ctsl/schema:layout-child-attrs
schema:bool-attrs
schema:shape-generic-attrs
schema:shape-base-attrs])
(def schema:shape-attrs
[:multi {:dispatch :type
:decode/json (fn [shape]

View File

@@ -175,21 +175,23 @@
[:url :string]])
(def schema:interaction
[:and {:title "Interaction"
:gen/gen (sg/one-of (sg/generator schema:navigate-interaction)
(sg/generator schema:open-overlay-interaction)
(sg/generator schema:close-overlay-interaction)
(sg/generator schema:toggle-overlay-interaction)
(sg/generator schema:prev-scren-interaction)
(sg/generator schema:open-url-interaction))}
schema:interaction-attrs
[:multi {:dispatch :action-type}
[:navigate schema:navigate-interaction]
[:open-overlay schema:open-overlay-interaction]
[:toggle-overlay schema:toggle-overlay-interaction]
[:close-overlay schema:close-overlay-interaction]
[:prev-screen schema:prev-scren-interaction]
[:open-url schema:open-url-interaction]]])
[:schema {:title "Interaction"
:gen/gen (sg/one-of (sg/generator schema:navigate-interaction)
(sg/generator schema:open-overlay-interaction)
(sg/generator schema:close-overlay-interaction)
(sg/generator schema:toggle-overlay-interaction)
(sg/generator schema:prev-scren-interaction)
(sg/generator schema:open-url-interaction))}
[:and
schema:interaction-attrs
[:multi {:dispatch :action-type}
;; [:navigate schema:navigate-interaction]
;; [:open-overlay schema:open-overlay-interaction]
;; [:toggle-overlay schema:toggle-overlay-interaction]
;; [:close-overlay schema:close-overlay-interaction]
;; [:prev-screen schema:prev-scren-interaction]
[:open-url schema:open-url-interaction]
]]])
(sm/register! ::interaction schema:interaction)

View File

@@ -8,6 +8,7 @@
(:require
[app.common.data :as d]
[app.common.schema :as sm]
[app.common.schema.desc-js-like :as smdj]
[clojure.data :as data]
[clojure.set :as set]
[malli.util :as mu]))
@@ -51,7 +52,8 @@
(into #{} (keys token-type->dtcg-token-type)))
(def token-name-ref
[:and :string [:re #"^(?!\$)([a-zA-Z0-9-$_]+\.?)*(?<!\.)$"]])
[:schema {:title "TokenNameRef"}
[:and :string [:re #"^(?!\$)([a-zA-Z0-9-$_]+\.?)*(?<!\.)$"]]])
(def ^:private schema:color
[:map
@@ -61,7 +63,7 @@
(def color-keys (schema-keys schema:color))
(def ^:private schema:border-radius
[:map
[:map {:title "BorderRadiusTokenAttrs"}
[:r1 {:optional true} token-name-ref]
[:r2 {:optional true} token-name-ref]
[:r3 {:optional true} token-name-ref]
@@ -76,7 +78,7 @@
(def stroke-width-keys (schema-keys schema:stroke-width))
(def ^:private schema:sizing
[:map
[:map {:title "SizingTokenAttrs"}
[:width {:optional true} token-name-ref]
[:height {:optional true} token-name-ref]
[:layout-item-min-w {:optional true} token-name-ref]
@@ -87,44 +89,46 @@
(def sizing-keys (schema-keys schema:sizing))
(def ^:private schema:opacity
[:map
[:map {:title "OpacityTokenAttrs"}
[:opacity {:optional true} token-name-ref]])
(def opacity-keys (schema-keys schema:opacity))
(def ^:private schema:spacing-gap
[:map
[:map {:title "SpacingGapTokenAttrs"}
[:row-gap {:optional true} token-name-ref]
[:column-gap {:optional true} token-name-ref]])
(def ^:private schema:spacing-padding
[:map
[:map {:title "SpacingPaddingTokenAttrs"}
[:p1 {:optional true} token-name-ref]
[:p2 {:optional true} token-name-ref]
[:p3 {:optional true} token-name-ref]
[:p4 {:optional true} token-name-ref]])
(def ^:private schema:spacing-margin
[:map
[:map {:title "SpacingMarginTokenAttrs"}
[:m1 {:optional true} token-name-ref]
[:m2 {:optional true} token-name-ref]
[:m3 {:optional true} token-name-ref]
[:m4 {:optional true} token-name-ref]])
(def ^:private schema:spacing
(reduce mu/union [schema:spacing-gap
schema:spacing-padding
schema:spacing-margin]))
(-> (reduce mu/union [schema:spacing-gap
schema:spacing-padding
schema:spacing-margin])
(mu/update-properties assoc :title "SpacingTokenAttrs")))
(def spacing-margin-keys (schema-keys schema:spacing-margin))
(def spacing-keys (schema-keys schema:spacing))
(def ^:private schema:dimensions
(reduce mu/union [schema:sizing
schema:spacing
schema:stroke-width
schema:border-radius]))
(-> (reduce mu/union [schema:sizing
schema:spacing
schema:stroke-width
schema:border-radius])
(mu/update-properties assoc :title "DimensionsTokenAttrs")))
(def dimensions-keys (schema-keys schema:dimensions))
@@ -135,22 +139,20 @@
(def axis-keys (schema-keys schema:axis))
(def ^:private schema:rotation
[:map
[:map {:title "RotationTokenAttrs"}
[:rotation {:optional true} token-name-ref]])
(def rotation-keys (schema-keys schema:rotation))
(def ^:private schema:font-size
[:map
[:map {:title "FontSizeTokenAttrs"}
[:font-size {:optional true} token-name-ref]])
(def font-size-keys (schema-keys schema:font-size))
(def ^:private schema:letter-spacing
[:map
[:map {:title "LetterSpacingTokenAttrs"}
[:letter-spacing {:optional true} token-name-ref]])
(def letter-spacing-keys (schema-keys schema:letter-spacing))
@@ -162,8 +164,9 @@
(def ff-typography-keys (set/difference typography-keys font-size-keys))
(def ^:private schema:number
(reduce mu/union [[:map [:line-height {:optional true} token-name-ref]]
schema:rotation]))
(-> (reduce mu/union [[:map [:line-height {:optional true} token-name-ref]]
schema:rotation])
(mu/update-properties assoc :title "NumberTokenAttrs")))
(def number-keys (schema-keys schema:number))
@@ -180,10 +183,10 @@
number-keys))
(def ^:private schema:tokens
[:map {:title "Applied Tokens"}])
[:map {:title "GenericTokenAttrs"}])
(def schema:applied-tokens
[:merge
[:merge {:title "AppliedTokens"}
schema:tokens
schema:border-radius
schema:sizing