From f052e31ff0b4c0e10f5f9fbd45bd53dcdc34800c Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 7 Aug 2025 09:29:19 +0200 Subject: [PATCH 01/11] :bug: Fix incorrect handling of assign operation on changes protocol --- common/src/app/common/files/changes.cljc | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/common/src/app/common/files/changes.cljc b/common/src/app/common/files/changes.cljc index afd1128e8a..c32f57a3b9 100644 --- a/common/src/app/common/files/changes.cljc +++ b/common/src/app/common/files/changes.cljc @@ -1091,21 +1091,23 @@ ;; === Operations -(def ^:private decode-shape - (sm/decoder cts/schema:shape sm/json-transformer)) +(def decode-shape-attrs + (sm/decoder cts/schema:shape-attrs sm/json-transformer)) (defmethod process-operation :assign [{:keys [type] :as shape} {:keys [value] :as op}] (let [modifications (assoc value :type type) - modifications (decode-shape modifications)] + modifications (decode-shape-attrs modifications)] (reduce-kv (fn [shape k v] - (process-operation shape {:type :set - :attr k - :val v - :ignore-touched (:ignore-touched op) - :ignore-geometry (:ignore-geometry op)})) + (if (not= v (get shape k)) + (process-operation shape {:type :set + :attr k + :val v + :ignore-touched (:ignore-touched op) + :ignore-geometry (:ignore-geometry op)}) + shape)) shape - modifications))) + (dissoc modifications :type)))) (defmethod process-operation :set [shape op] From d9623c3c88128e8c0985f91199a82aa210bda880 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 14 Aug 2025 07:43:45 +0200 Subject: [PATCH 02/11] :bug: Add proper schema for decoding :obj on add-obj change --- common/src/app/common/files/changes.cljc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/app/common/files/changes.cljc b/common/src/app/common/files/changes.cljc index c32f57a3b9..d38a78e307 100644 --- a/common/src/app/common/files/changes.cljc +++ b/common/src/app/common/files/changes.cljc @@ -196,7 +196,7 @@ [:map {:title "AddObjChange"} [:type [:= :add-obj]] [:id ::sm/uuid] - [:obj :map] + [:obj cts/schema:shape] [:page-id {:optional true} ::sm/uuid] [:component-id {:optional true} ::sm/uuid] [:frame-id ::sm/uuid] From edd3b1512e8f9c0e840e317e29b16842b31fb593 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 18 Aug 2025 13:14:44 +0200 Subject: [PATCH 03/11] :bug: Add missing attrs to add-component change schema --- common/src/app/common/files/changes.cljc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/common/src/app/common/files/changes.cljc b/common/src/app/common/files/changes.cljc index d38a78e307..344cf2c9a5 100644 --- a/common/src/app/common/files/changes.cljc +++ b/common/src/app/common/files/changes.cljc @@ -329,7 +329,9 @@ [:id ::sm/uuid] [:name :string] [:shapes {:optional true} [:vector {:gen/max 3} ::sm/any]] - [:path {:optional true} :string]]] + [:path {:optional true} :string] + [:main-instance-id ::sm/uuid] + [:main-instance-page ::sm/uuid]]] [:mod-component [:map {:title "ModCompoenentChange"} From 43ed43047561b9abd7feb790d9bd5928da5106fe Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 19 Aug 2025 10:29:03 +0200 Subject: [PATCH 04/11] :paperclip: Update .gitignore file --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b4ea7ee77c..c8f4cfc13a 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,7 @@ /.clj-kondo/.cache /_dump /notes +/playground/ /backend/*.md /backend/*.sql /backend/*.txt From 124b098c922184a7e9ad1df06921aac951e700af Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 19 Aug 2025 10:29:14 +0200 Subject: [PATCH 05/11] :fire: Remove already deprecated change spec --- common/src/app/common/files/changes.cljc | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/common/src/app/common/files/changes.cljc b/common/src/app/common/files/changes.cljc index 344cf2c9a5..2ea75ada33 100644 --- a/common/src/app/common/files/changes.cljc +++ b/common/src/app/common/files/changes.cljc @@ -178,12 +178,6 @@ :title "Change" :decode/json #(update % :type keyword) ::smd/simplified true} - [:set-option - - ;; DEPRECATED: remove before 2.3 release - ;; - ;; Is still there for not cause error when event is received - [:map {:title "SetOptionChange"}]] [:set-comment-thread-position [:map @@ -549,11 +543,6 @@ #?(:clj (validate-shapes! data result items)) result)))) -;; DEPRECATED: remove after 2.3 release -(defmethod process-change :set-option - [data _] - data) - ;; --- Comment Threads (defmethod process-change :set-comment-thread-position From 545c78eb74bc6c3203da2fdbe2ed0a60f8d36801 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 19 Aug 2025 10:29:52 +0200 Subject: [PATCH 06/11] :bug: Add missing generators --- common/src/app/common/types/tokens_lib.cljc | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/common/src/app/common/types/tokens_lib.cljc b/common/src/app/common/types/tokens_lib.cljc index 8cf5b946fa..0f6601586e 100644 --- a/common/src/app/common/types/tokens_lib.cljc +++ b/common/src/app/common/types/tokens_lib.cljc @@ -543,18 +543,17 @@ (get-ordered-set-names [_] "get an ordered sequence of all sets names in the library") (get-set [_ set-name] "get one set looking for name")) -(def schema:token-set-node - [:schema {:registry {::node [:or [:fn token-set?] - [:and - [:map-of {:gen/max 5} :string [:ref ::node]] - [:fn d/ordered-map?]]]}} +(def ^:private schema:token-set-node + [:schema {:registry {::node + [:or [:fn token-set?] + [:and + [:map-of {:gen/max 5} :string [:ref ::node]] + [:fn d/ordered-map?]]]}} [:ref ::node]]) -(def schema:token-sets - [:and - [:map-of {:title "TokenSets"} - :string - schema:token-set-node] +(def ^:private schema:token-sets + [:and {:title "TokenSets"} + [:map-of :string schema:token-set-node] [:fn d/ordered-map?]]) (def ^:private check-token-sets From 911ac263faaff5105afd45fef23b1ce2c05219e6 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 19 Aug 2025 11:32:41 +0200 Subject: [PATCH 07/11] :bug: Use ::sm/any instead of any for get-file-fragment rpc method schema The usage of `any?` predicate as-is uses the standard any generator that causes to generate java.lang.Character instances created that are not properly serialiable to JSON. The `::sm/any` schema delimits the generator to a commonly known serializable types on json. --- backend/src/app/rpc/commands/files.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/app/rpc/commands/files.clj b/backend/src/app/rpc/commands/files.clj index 5adef0050c..8916b74d9a 100644 --- a/backend/src/app/rpc/commands/files.clj +++ b/backend/src/app/rpc/commands/files.clj @@ -357,7 +357,7 @@ [:id ::sm/uuid] [:file-id ::sm/uuid] [:created-at ::ct/inst] - [:content any?]]) + [:content ::sm/any]]) (def schema:get-file-fragment [:map {:title "get-file-fragment"} From 2b83d0d0e993c702c8f5f75f66df51c3dc5a0d9d Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 19 Aug 2025 11:34:50 +0200 Subject: [PATCH 08/11] :sparkles: Add generative test case for openapi json serialization This will prevent possible regression on introducing schemas without generators or schema with generators that can't be serialized to json. --- backend/test/backend_tests/rpc_doc_test.clj | 36 +++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 backend/test/backend_tests/rpc_doc_test.clj diff --git a/backend/test/backend_tests/rpc_doc_test.clj b/backend/test/backend_tests/rpc_doc_test.clj new file mode 100644 index 0000000000..fb6c2c106d --- /dev/null +++ b/backend/test/backend_tests/rpc_doc_test.clj @@ -0,0 +1,36 @@ +;; 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 backend-tests.rpc-doc-test + "Internal binfile test, no RPC involved" + (:require + [app.common.json :as json] + [app.common.pprint :as pp] + [app.common.schema :as sm] + [app.common.schema.generators :as sg] + [app.common.schema.test :as smt] + [app.rpc :as-alias rpc] + [app.rpc.doc :as rpc.doc] + [backend-tests.helpers :as th] + [clojure.test :as t])) + +(t/use-fixtures :once th/state-init) + +(t/deftest openapi-context-json-encode + (smt/check! + (smt/for [context (->> sg/int + (sg/fmap (fn [_] + (rpc.doc/prepare-openapi-context (::rpc/methods th/*system*)))))] + (try + (json/encode context) + true + (catch Throwable _cause + false))) + {:num 30})) + + + + From b472a8ab19d1de2ccd289e05db33fdcb163bca88 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 19 Aug 2025 14:09:07 +0200 Subject: [PATCH 09/11] :sparkles: Add general improvement to openapi and js-like doc output --- backend/dev/user.clj | 1 + backend/src/app/rpc/commands/fonts.clj | 15 +- backend/src/app/rpc/doc.clj | 3 - common/src/app/common/files/changes.cljc | 463 +++++++++--------- common/src/app/common/schema.cljc | 52 +- .../src/app/common/schema/desc_js_like.cljc | 210 ++++---- common/src/app/common/schema/openapi.cljc | 131 +++-- common/src/app/common/types/color.cljc | 19 +- common/src/app/common/types/grid.cljc | 12 +- common/src/app/common/types/path/impl.cljc | 4 +- common/src/app/common/types/plugins.cljc | 2 +- common/src/app/common/types/shape.cljc | 2 +- .../app/common/types/shape/interactions.cljc | 47 +- common/src/app/common/types/shape/shadow.cljc | 6 +- common/src/app/common/types/token.cljc | 49 +- 15 files changed, 550 insertions(+), 466 deletions(-) diff --git a/backend/dev/user.clj b/backend/dev/user.clj index 74d042d86b..522b5ae643 100644 --- a/backend/dev/user.clj +++ b/backend/dev/user.clj @@ -18,6 +18,7 @@ [app.common.schema :as sm] [app.common.schema.desc-js-like :as smdj] [app.common.schema.desc-native :as smdn] + [app.common.schema.openapi :as oapi] [app.common.schema.generators :as sg] [app.common.spec :as us] [app.common.json :as json] diff --git a/backend/src/app/rpc/commands/fonts.clj b/backend/src/app/rpc/commands/fonts.clj index e5a0b71c1b..c417c28f1a 100644 --- a/backend/src/app/rpc/commands/fonts.clj +++ b/backend/src/app/rpc/commands/fonts.clj @@ -37,14 +37,13 @@ (def ^:private schema:get-font-variants - [:schema {:title "get-font-variants"} - [:and - [:map - [:team-id {:optional true} ::sm/uuid] - [:file-id {:optional true} ::sm/uuid] - [:project-id {:optional true} ::sm/uuid] - [:share-id {:optional true} ::sm/uuid]] - [::sm/contains-any #{:team-id :file-id :project-id}]]]) + [:and + [:map {:title "get-font-variants"} + [:team-id {:optional true} ::sm/uuid] + [:file-id {:optional true} ::sm/uuid] + [:project-id {:optional true} ::sm/uuid] + [:share-id {:optional true} ::sm/uuid]] + [::sm/contains-any #{:team-id :file-id :project-id}]]) (sv/defmethod ::get-font-variants {::doc/added "1.18" diff --git a/backend/src/app/rpc/doc.clj b/backend/src/app/rpc/doc.clj index cba16e0ab5..52bdcbc6a9 100644 --- a/backend/src/app/rpc/doc.clj +++ b/backend/src/app/rpc/doc.clj @@ -166,9 +166,6 @@ :servers [{:url (str/ffmt "%/api/rpc" (cf/get :public-uri)) ;; :description "penpot backend" }] - :security - {:api_key []} - :paths paths :components {:schemas @definitions}})) diff --git a/common/src/app/common/files/changes.cljc b/common/src/app/common/files/changes.cljc index 2ea75ada33..e0ff3917a5 100644 --- a/common/src/app/common/files/changes.cljc +++ b/common/src/app/common/files/changes.cljc @@ -83,24 +83,25 @@ [:multi {:decode/json #(update % :grid-type keyword) :gen/gen gen + :title "SetDefaultGridChange" :dispatch :grid-type ::smd/simplified true} [:square - [:map + [:map {:title "SetDefautSquareGridAttrs"} [:type [:= :set-default-grid]] [:page-id ::sm/uuid] [:grid-type [:= :square]] [:params [:maybe ctg/schema:square-params]]]] [:column - [:map + [:map {:title "SetDefaultColumnGridAttrs"} [:type [:= :set-default-grid]] [:page-id ::sm/uuid] [:grid-type [:= :column]] [:params [:maybe ctg/schema:column-params]]]] [:row - [:map + [:map {:title "SetDefaultRowGridAttrs"} [:type [:= :set-default-grid]] [:page-id ::sm/uuid] [:grid-type [:= :row]] @@ -117,7 +118,7 @@ (if (some? (:params change)) (update change :params assoc :id (:id change)) change))))] - [:schema {:gen/gen gen} schema])) + (sm/update-properties schema assoc :gen/gen gen))) (def schema:set-flow-change (let [schema [:map {:title "SetFlowChange"} @@ -132,7 +133,7 @@ (update change :params assoc :id (:id change)) change))))] - [:schema {:gen/gen gen} schema])) + (sm/update-properties schema assoc :gen/gen gen))) (def schema:set-plugin-data-change (let [types #{:file :page :shape :color :typography :component} @@ -169,272 +170,266 @@ :else (dissoc change :page-id)))))] - - [:and {:gen/gen gen} schema check1])) + [:and (sm/update-properties schema assoc :gen/gen gen) check1])) (def schema:change - [:schema - [:multi {:dispatch :type - :title "Change" - :decode/json #(update % :type keyword) - ::smd/simplified true} + [:multi {:dispatch :type + :title "Change" + :decode/json #(update % :type keyword) + ::smd/simplified true} - [:set-comment-thread-position - [:map - [:comment-thread-id ::sm/uuid] - [:page-id ::sm/uuid] - [:frame-id [:maybe ::sm/uuid]] - [:position [:maybe ::gpt/point]]]] + [:set-comment-thread-position + [:map {:title "SetCommentThreadPositionChange"} + [:comment-thread-id ::sm/uuid] + [:page-id ::sm/uuid] + [:frame-id [:maybe ::sm/uuid]] + [:position [:maybe ::gpt/point]]]] - [:add-obj - [:map {:title "AddObjChange"} - [:type [:= :add-obj]] - [:id ::sm/uuid] - [:obj cts/schema:shape] - [:page-id {:optional true} ::sm/uuid] - [:component-id {:optional true} ::sm/uuid] - [:frame-id ::sm/uuid] - [:parent-id {:optional true} [:maybe ::sm/uuid]] - [:index {:optional true} [:maybe :int]] - [:ignore-touched {:optional true} :boolean]]] + [:add-obj + [:map {:title "AddObjChange"} + [:type [:= :add-obj]] + [:id ::sm/uuid] + [:obj cts/schema:shape] + [:page-id {:optional true} ::sm/uuid] + [:component-id {:optional true} ::sm/uuid] + [:frame-id ::sm/uuid] + [:parent-id {:optional true} [:maybe ::sm/uuid]] + [:index {:optional true} [:maybe :int]] + [:ignore-touched {:optional true} :boolean]]] - [:mod-obj - [:map {:title "ModObjChange"} - [:type [:= :mod-obj]] - [:id ::sm/uuid] - [:page-id {:optional true} ::sm/uuid] - [:component-id {:optional true} ::sm/uuid] - [:operations [:vector {:gen/max 5} schema:operation]]]] + [:mod-obj + [:map {:title "ModObjChange"} + [:type [:= :mod-obj]] + [:id ::sm/uuid] + [:page-id {:optional true} ::sm/uuid] + [:component-id {:optional true} ::sm/uuid] + [:operations [:vector {:gen/max 5} schema:operation]]]] - [:del-obj - [:map {:title "DelObjChange"} - [:type [:= :del-obj]] - [:id ::sm/uuid] - [:page-id {:optional true} ::sm/uuid] - [:component-id {:optional true} ::sm/uuid] - [:ignore-touched {:optional true} :boolean]]] + [:del-obj + [:map {:title "DelObjChange"} + [:type [:= :del-obj]] + [:id ::sm/uuid] + [:page-id {:optional true} ::sm/uuid] + [:component-id {:optional true} ::sm/uuid] + [:ignore-touched {:optional true} :boolean]]] - [:set-guide schema:set-guide-change] - [:set-flow schema:set-flow-change] - [:set-default-grid schema:set-default-grid-change] + [:set-guide schema:set-guide-change] + [:set-flow schema:set-flow-change] + [:set-default-grid schema:set-default-grid-change] - [:fix-obj - [:map {:title "FixObjChange"} - [:type [:= :fix-obj]] - [:id ::sm/uuid] - [:fix {:optional true} :keyword] - [:page-id {:optional true} ::sm/uuid] - [:component-id {:optional true} ::sm/uuid]]] + [:fix-obj + [:map {:title "FixObjChange"} + [:type [:= :fix-obj]] + [:id ::sm/uuid] + [:fix {:optional true} :keyword] + [:page-id {:optional true} ::sm/uuid] + [:component-id {:optional true} ::sm/uuid]]] - [:mov-objects - [:map {:title "MovObjectsChange"} - [:type [:= :mov-objects]] - [:page-id {:optional true} ::sm/uuid] - [:component-id {:optional true} ::sm/uuid] - [:ignore-touched {:optional true} :boolean] - [:parent-id ::sm/uuid] - [:shapes ::sm/any] - [:index {:optional true} [:maybe :int]] - [:after-shape {:optional true} ::sm/any] - [:allow-altering-copies {:optional true} :boolean]]] + [:mov-objects + [:map {:title "MovObjectsChange"} + [:type [:= :mov-objects]] + [:page-id {:optional true} ::sm/uuid] + [:component-id {:optional true} ::sm/uuid] + [:ignore-touched {:optional true} :boolean] + [:parent-id ::sm/uuid] + [:shapes ::sm/any] + [:index {:optional true} [:maybe :int]] + [:after-shape {:optional true} ::sm/any] + [:allow-altering-copies {:optional true} :boolean]]] - [:reorder-children - [:map {:title "ReorderChildrenChange"} - [:type [:= :reorder-children]] - [:page-id {:optional true} ::sm/uuid] - [:component-id {:optional true} ::sm/uuid] - [:ignore-touched {:optional true} :boolean] - [:parent-id ::sm/uuid] - [:shapes ::sm/any]]] + [:reorder-children + [:map {:title "ReorderChildrenChange"} + [:type [:= :reorder-children]] + [:page-id {:optional true} ::sm/uuid] + [:component-id {:optional true} ::sm/uuid] + [:ignore-touched {:optional true} :boolean] + [:parent-id ::sm/uuid] + [:shapes ::sm/any]]] - [:add-page - [:map {:title "AddPageChange"} - [:type [:= :add-page]] - [:id {:optional true} ::sm/uuid] - [:name {:optional true} :string] - [:page {:optional true} ::sm/any]]] + [:add-page + [:map {:title "AddPageChange"} + [:type [:= :add-page]] + [:id {:optional true} ::sm/uuid] + [:name {:optional true} :string] + [:page {:optional true} ::sm/any]]] - [:mod-page - [:map {:title "ModPageChange"} - [:type [:= :mod-page]] - [:id ::sm/uuid] - ;; All props are optional, background can be nil because is the - ;; way to remove already set background - [:background {:optional true} [:maybe ctc/schema:hex-color]] - [:name {:optional true} :string]]] + [:mod-page + [:map {:title "ModPageChange"} + [:type [:= :mod-page]] + [:id ::sm/uuid] + ;; All props are optional, background can be nil because is the + ;; way to remove already set background + [:background {:optional true} [:maybe ctc/schema:hex-color]] + [:name {:optional true} :string]]] - [:set-plugin-data schema:set-plugin-data-change] + [:set-plugin-data schema:set-plugin-data-change] - [:del-page - [:map {:title "DelPageChange"} - [:type [:= :del-page]] - [:id ::sm/uuid]]] + [:del-page + [:map {:title "DelPageChange"} + [:type [:= :del-page]] + [:id ::sm/uuid]]] - [:mov-page - [:map {:title "MovPageChange"} - [:type [:= :mov-page]] - [:id ::sm/uuid] - [:index :int]]] + [:mov-page + [:map {:title "MovPageChange"} + [:type [:= :mov-page]] + [:id ::sm/uuid] + [:index :int]]] - [:reg-objects - [:map {:title "RegObjectsChange"} - [:type [:= :reg-objects]] - [:page-id {:optional true} ::sm/uuid] - [:component-id {:optional true} ::sm/uuid] - [:shapes [:vector {:gen/max 5} ::sm/uuid]]]] + [:reg-objects + [:map {:title "RegObjectsChange"} + [:type [:= :reg-objects]] + [:page-id {:optional true} ::sm/uuid] + [:component-id {:optional true} ::sm/uuid] + [:shapes [:vector {:gen/max 5} ::sm/uuid]]]] - [:add-color - [:map {:title "AddColorChange"} - [:type [:= :add-color]] - [:color ctc/schema:library-color]]] + [:add-color + [:map {:title "AddColorChange"} + [:type [:= :add-color]] + [:color ctc/schema:library-color]]] - [:mod-color - [:map {:title "ModColorChange"} - [:type [:= :mod-color]] - [:color ctc/schema:library-color]]] + [:mod-color + [:map {:title "ModColorChange"} + [:type [:= :mod-color]] + [:color ctc/schema:library-color]]] - [:del-color - [:map {:title "DelColorChange"} - [:type [:= :del-color]] - [:id ::sm/uuid]]] + [:del-color + [:map {:title "DelColorChange"} + [:type [:= :del-color]] + [:id ::sm/uuid]]] - ;; DEPRECATED: remove before 2.3 - [:add-recent-color - [:map {:title "AddRecentColorChange"}]] + [:add-media + [:map {:title "AddMediaChange"} + [:type [:= :add-media]] + [:object ctf/schema:media]]] - [:add-media - [:map {:title "AddMediaChange"} - [:type [:= :add-media]] - [:object ctf/schema:media]]] + [:mod-media + [:map {:title "ModMediaChange"} + [:type [:= :mod-media]] + [:object ctf/schema:media]]] - [:mod-media - [:map {:title "ModMediaChange"} - [:type [:= :mod-media]] - [:object ctf/schema:media]]] + [:del-media + [:map {:title "DelMediaChange"} + [:type [:= :del-media]] + [:id ::sm/uuid]]] - [:del-media - [:map {:title "DelMediaChange"} - [:type [:= :del-media]] - [:id ::sm/uuid]]] + [:add-component + [:map {:title "AddComponentChange"} + [:type [:= :add-component]] + [:id ::sm/uuid] + [:name :string] + [:shapes {:optional true} [:vector {:gen/max 3} ::sm/any]] + [:path {:optional true} :string] + [:main-instance-id ::sm/uuid] + [:main-instance-page ::sm/uuid]]] - [:add-component - [:map {:title "AddComponentChange"} - [:type [:= :add-component]] - [:id ::sm/uuid] - [:name :string] - [:shapes {:optional true} [:vector {:gen/max 3} ::sm/any]] - [:path {:optional true} :string] - [:main-instance-id ::sm/uuid] - [:main-instance-page ::sm/uuid]]] + [:mod-component + [:map {:title "ModCompoenentChange"} + [:type [:= :mod-component]] + [:id ::sm/uuid] + [:shapes {:optional true} [:vector {:gen/max 3} ::sm/any]] + [:name {:optional true} :string] + [:variant-id {:optional true} ::sm/uuid] + [:variant-properties {:optional true} [:vector ::ctv/variant-property]]]] - [:mod-component - [:map {:title "ModCompoenentChange"} - [:type [:= :mod-component]] - [:id ::sm/uuid] - [:shapes {:optional true} [:vector {:gen/max 3} ::sm/any]] - [:name {:optional true} :string] - [:variant-id {:optional true} ::sm/uuid] - [:variant-properties {:optional true} [:vector ::ctv/variant-property]]]] + [:del-component + [:map {:title "DelComponentChange"} + [:type [:= :del-component]] + [:id ::sm/uuid] + ;; when it is an undo of a cut-paste, we need to undo the movement + ;; of the shapes so we need to move them delta + [:delta {:optional true} ::gpt/point] + [:skip-undelete? {:optional true} :boolean]]] - [:del-component - [:map {:title "DelComponentChange"} - [:type [:= :del-component]] - [:id ::sm/uuid] - ;; when it is an undo of a cut-paste, we need to undo the movement - ;; of the shapes so we need to move them delta - [:delta {:optional true} ::gpt/point] - [:skip-undelete? {:optional true} :boolean]]] + [:restore-component + [:map {:title "RestoreComponentChange"} + [:type [:= :restore-component]] + [:id ::sm/uuid] + [:page-id ::sm/uuid]]] - [:restore-component - [:map {:title "RestoreComponentChange"} - [:type [:= :restore-component]] - [:id ::sm/uuid] - [:page-id ::sm/uuid]]] + [:purge-component + [:map {:title "PurgeComponentChange"} + [:type [:= :purge-component]] + [:id ::sm/uuid]]] - [:purge-component - [:map {:title "PurgeComponentChange"} - [:type [:= :purge-component]] - [:id ::sm/uuid]]] + [:add-typography + [:map {:title "AddTypogrphyChange"} + [:type [:= :add-typography]] + [:typography ::ctt/typography]]] - [:add-typography - [:map {:title "AddTypogrphyChange"} - [:type [:= :add-typography]] - [:typography ::ctt/typography]]] + [:mod-typography + [:map {:title "ModTypogrphyChange"} + [:type [:= :mod-typography]] + [:typography ::ctt/typography]]] - [:mod-typography - [:map {:title "ModTypogrphyChange"} - [:type [:= :mod-typography]] - [:typography ::ctt/typography]]] + [:del-typography + [:map {:title "DelTypogrphyChange"} + [:type [:= :del-typography]] + [:id ::sm/uuid]]] - [:del-typography - [:map {:title "DelTypogrphyChange"} - [:type [:= :del-typography]] - [:id ::sm/uuid]]] + [:update-active-token-themes + [:map {:title "UpdateActiveTokenThemes"} + [:type [:= :update-active-token-themes]] + [:theme-paths [:set :string]]]] - [:update-active-token-themes - [:map {:title "UpdateActiveTokenThemes"} - [:type [:= :update-active-token-themes]] - [:theme-paths [:set :string]]]] + [:rename-token-set-group + [:map {:title "RenameTokenSetGroup"} + [:type [:= :rename-token-set-group]] + [:set-group-path [:vector :string]] + [:set-group-fname :string]]] - [:rename-token-set-group - [:map {:title "RenameTokenSetGroup"} - [:type [:= :rename-token-set-group]] - [:set-group-path [:vector :string]] - [:set-group-fname :string]]] + [:move-token-set + [:map {:title "MoveTokenSet"} + [:type [:= :move-token-set]] + [:from-path [:vector :string]] + [:to-path [:vector :string]] + [:before-path [:maybe [:vector :string]]] + [:before-group [:maybe :boolean]]]] - [:move-token-set - [:map {:title "MoveTokenSet"} - [:type [:= :move-token-set]] - [:from-path [:vector :string]] - [:to-path [:vector :string]] - [:before-path [:maybe [:vector :string]]] - [:before-group [:maybe :boolean]]]] + [:move-token-set-group + [:map {:title "MoveTokenSetGroup"} + [:type [:= :move-token-set-group]] + [:from-path [:vector :string]] + [:to-path [:vector :string]] + [:before-path [:maybe [:vector :string]]] + [:before-group [:maybe :boolean]]]] - [:move-token-set-group - [:map {:title "MoveTokenSetGroup"} - [:type [:= :move-token-set-group]] - [:from-path [:vector :string]] - [:to-path [:vector :string]] - [:before-path [:maybe [:vector :string]]] - [:before-group [:maybe :boolean]]]] + [:set-token-theme + [:map {:title "SetTokenThemeChange"} + [:type [:= :set-token-theme]] + [:theme-name :string] + [:group :string] + [:theme [:maybe ctob/schema:token-theme-attrs]]]] - [:set-token-theme - [:map {:title "SetTokenThemeChange"} - [:type [:= :set-token-theme]] - [:theme-name :string] - [:group :string] - [:theme [:maybe ctob/schema:token-theme-attrs]]]] + [:set-tokens-lib + [:map {:title "SetTokensLib"} + [:type [:= :set-tokens-lib]] + [:tokens-lib ::sm/any]]] - [:set-tokens-lib - [:map {:title "SetTokensLib"} - [:type [:= :set-tokens-lib]] - [:tokens-lib ::sm/any]]] + [:set-token-set + [:map {:title "SetTokenSetChange"} + [:type [:= :set-token-set]] + [:set-name :string] + [:group? :boolean] - [:set-token-set - [:map {:title "SetTokenSetChange"} - [:type [:= :set-token-set]] - [:set-name :string] - [:group? :boolean] + ;; FIXME: we should not pass private types as part of changes + ;; protocol, the changes protocol should reflect a + ;; method/protocol for perform surgical operations on file data, + ;; this has nothing todo with internal types of a file data + ;; structure. + [:token-set {:gen/gen (sg/generator ctob/schema:token-set)} + [:maybe [:fn ctob/token-set?]]]]] - ;; FIXME: we should not pass private types as part of changes - ;; protocol, the changes protocol should reflect a - ;; method/protocol for perform surgical operations on file data, - ;; this has nothing todo with internal types of a file data - ;; structure. - [:token-set {:gen/gen (sg/generator ctob/schema:token-set)} - [:maybe [:fn ctob/token-set?]]]]] + [:set-token + [:map {:title "SetTokenChange"} + [:type [:= :set-token]] + [:set-name :string] + [:token-id ::sm/uuid] + [:token [:maybe ctob/schema:token-attrs]]]] - [:set-token - [:map {:title "SetTokenChange"} - [:type [:= :set-token]] - [:set-name :string] - [:token-id ::sm/uuid] - [:token [:maybe ctob/schema:token-attrs]]]] - - [:set-base-font-size - [:map {:title "ModBaseFontSize"} - [:type [:= :set-base-font-size]] - [:base-font-size :string]]]]]) + [:set-base-font-size + [:map {:title "ModBaseFontSize"} + [:type [:= :set-base-font-size]] + [:base-font-size :string]]]]) (def schema:changes [:sequential {:gen/max 5 :gen/min 1} schema:change]) @@ -936,12 +931,6 @@ [data {:keys [id]}] (ctl/delete-color data id)) -;; DEPRECATED: remove before 2.3 -(defmethod process-change :add-recent-color - [data _] - data) - - ;; -- Media (defmethod process-change :add-media diff --git a/common/src/app/common/schema.cljc b/common/src/app/common/schema.cljc index 70281ff419..54edcf599e 100644 --- a/common/src/app/common/schema.cljc +++ b/common/src/app/common/schema.cljc @@ -131,34 +131,10 @@ (->> (entries schema) (into #{} xf:map-key))) - -;; (defn key-transformer -;; [& {:as opts}] -;; (mt/key-transformer opts)) - -;; (defn- transform-map-keys -;; [f o] -;; (cond -;; (record? o) -;; (reduce-kv (fn [res k v] -;; (let [k' (f k)] -;; (if (= k k') -;; res -;; (-> res -;; (assoc k' v) -;; (dissoc k))))) -;; o -;; o) - -;; (map? o) -;; (persistent! -;; (reduce-kv (fn [res k v] -;; (assoc! res (f k) v)) -;; (transient {}) -;; o)) - -;; :else -;; o)) +(defn update-properties + [s f & args] + (let [s (schema s)] + (apply m/-update-properties s f args))) (defn -transform-map-keys ([f] @@ -679,8 +655,7 @@ identity)] {:pred #(contains? options %) :type-properties - {:title "one-of" - :description "One of the Set" + {:title "enum" :gen/gen (sg/elements options) :decode/string decode :decode/json decode @@ -723,15 +698,14 @@ {:pred pred :type-properties - {:title "int" - :description "int" + {:title "integer" + :description "integer" :error/message "expected to be int/long" :error/code "errors.invalid-integer" :gen/gen gen :decode/string parse-long :decode/json parse-long - ::oapi/type "integer" - ::oapi/format "int64"}}))}) + ::oapi/type "integer"}}))}) (defn parse-double [v] @@ -793,8 +767,8 @@ {:pred pred :type-properties - {:title "int" - :description "int" + {:title "number" + :description "number" :error/message "expected to be number" :error/code "errors.invalid-number" :gen/gen gen @@ -844,10 +818,7 @@ #(some (fn [prop] (contains? % prop)) choices))] - {:pred pred - :type-properties - {:title "contains any" - :description "contains predicate"}}))}) + {:pred pred}))}) ;; (register! ;; {:type ::inst @@ -968,6 +939,7 @@ :type-properties {:title "string" :description "not whitespace string" + ::oapi/type "string" :gen/gen (sg/word-string) :error/fn (fn [{:keys [value schema]}] diff --git a/common/src/app/common/schema/desc_js_like.cljc b/common/src/app/common/schema/desc_js_like.cljc index f61279378c..74c4a4cb48 100644 --- a/common/src/app/common/schema/desc_js_like.cljc +++ b/common/src/app/common/schema/desc_js_like.cljc @@ -91,11 +91,15 @@ (defmethod visit :int [_ schema _ _] (str "integer" (-titled schema) (-min-max-suffix-number schema))) (defmethod visit :double [_ schema _ _] (str "double" (-titled schema) (-min-max-suffix-number schema))) (defmethod visit :select-keys [_ schema _ options] (describe* (m/deref schema) options)) -(defmethod visit :and [_ s children _] (str (str/join " && " children) (-titled s))) +(defmethod visit :and [_ s children _] + (str (str/join " && " (filter some? children)) (-titled s))) (defmethod visit :enum [_ s children _options] (str "enum" (-titled s) " of " (str/join ", " children))) (defmethod visit :maybe [_ _ children _] (str (first children) " nullable")) (defmethod visit :tuple [_ _ children _] (str "(" (str/join ", " children) ")")) -(defmethod visit :re [_ s _ options] (str "regex pattern " (-titled s) "matching " (pr-str (first (m/children s options))))) +(defmethod visit :re [_ _ children _] + (let [pattern (first children)] + (str "string & regex pattern /" (str pattern) "/"))) + (defmethod visit :any [_ s _ _] (str "anything" (-titled s))) (defmethod visit :some [_ _ _ _] "anything but null") (defmethod visit :nil [_ _ _ _] "null") @@ -108,10 +112,11 @@ (defmethod visit :uuid [_ _ _ _] "uuid") (defmethod visit :boolean [_ _ _ _] "boolean") (defmethod visit :keyword [_ _ _ _] "string") -(defmethod visit :fn [_ _ _ _] "FN") +(defmethod visit :fn [_ _ _ _] + nil) (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 +142,15 @@ (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 +168,104 @@ (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) + 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 " " (str/camel k) + (when (contains? optional k) "?") + ": " (str/trim s)))) + (str/join ",\n")) + + header (cond-> (str "type " title) + closed? (str "!") + (some? title) (str " "))] + + (str header "{\n" entries "\n}"))) + (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)] + [_ schema children {:keys [::level] :as options}] + (let [props (m/properties schema) + extracted? (get props ::extracted false)] - (if (>= level max-level) - (or (some-> title str) - "") - (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")) + (cond + (or (= level 0) extracted?) + (format-map schema children) - header (cond-> (str "type " title) - closed? (str "!") - (some? title) (str " "))] + :else + (let [schema (mu/update-properties schema assoc ::extracted true) + title (or (some->> (:title props) str/camel str/capital) "")] + (swap! *definitions* conj (format-map schema children)) + title)))) - (str (pad header level) "{\n" entries "\n" (pad "}\n" level)))))) +(defn format-multi + [s children] + (let [props (m/properties s) + title (or (some-> (:title props) str/camel str/capital) "") + dispatcher (or (-> s m/properties :dispatch-description) + (-> s m/properties :dispatch)) + entries (->> children + (map (fn [[_ _ entry]] + (pad entry 1))) + (str/join ",\n")) + + header (str "type " title " [dispatch=" (d/name dispatcher) "]")] + (str header " {\n" entries "\n}"))) (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)) + [_ schema children {:keys [::level] :as options}] + (let [props (m/properties schema) + title (or (some-> (:title props) str/camel str/capital) "") + extracted? (get props ::extracted false)] - prefix (apply str (take (inc level) (repeat " "))) + (cond + (or (zero? level) extracted?) + (format-multi schema children) - entries (->> children - (map (fn [[_ _ shape]] - (str prefix shape))) - (str/join ",\n")) + :else + (let [schema (mu/update-properties schema assoc ::extracted true)] + (swap! *definitions* conj (format-multi schema children)) + title)))) - header (cond-> "multi" - (some? title) (str " " title) - :always (str " [dispatch=" (d/name dispatcher) "]"))] +(defn- format-merge + [schema children] - (str header " {\n" entries "\n" (pad "}" level)))))) + (let [props (m/properties schema) + entries (->> children + (map (fn [shape] + (pad shape 1))) + (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) - "")] - (str "merge type " title " { \n" entries "\n}\n"))) + [_ schema children {:keys [::level] :as options}] + (let [props (m/properties schema) + title (some-> (:title props) str/camel str/capital) + extracted? (get props ::extracted false)] + + (cond + (or (zero? level) extracted?) + (format-merge schema children) + + :else + (let [schema (mu/update-properties schema assoc ::extracted true)] + (swap! *definitions* conj + (format-merge schema children)) + title)))) (defmethod visit ::sm/one-of [_ _ children _] @@ -219,45 +274,37 @@ (map d/name) (str/join "|")) ")"))) -(defmethod visit :schema [_ schema children options] - (visit ::m/schema schema children options)) - -(defmethod visit ::m/schema - [_ schema _ {:keys [::level ::limit ::max-level] :as options}] - (let [schema' (m/deref schema) - props (merge - (m/properties schema) - (m/properties schema')) - ref (m/-ref schema) - title (:title props)] +(defmethod visit :schema + [_ schema children options] + (let [props (m/properties schema) + title (some-> (:title props) str/camel str/capital) + extracted? (get props ::extracted false)] (cond - (::inline props) - (do - (if (>= limit max-level) - title - (describe* schema' options))) + (not title) + (visit ::m/schema schema children options) - (and ref title) - (do - (when (<= limit max-level) - (swap! *definitions* conj (describe* schema' (assoc options ::base-limit limit)))) - - title) - - (>= limit max-level) - (or title - (some-> ref d/name str/camel str/capital) - "") + extracted? + (let [title (or title "")] + (str "type " title ": " + (visit ::m/schema schema children options))) :else - (describe* schema' (assoc options ::base-level level ::base-limit limit))))) + (let [schema (mu/update-properties schema assoc ::extracted true) + title (or title "")] + (swap! *definitions* conj + (str "type " title ": " + (visit ::m/schema schema children (update options ::level inc)))) + title)))) + +(defmethod visit ::m/schema + [_ schema _ {:keys [::level] :as options}] + (let [schema' (m/deref schema)] + (describe* schema' (assoc options ::base-level level)))) (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] :or {base-level 0} :as options}] + (let [options (assoc options ::level (+ base-level (count path)))] (visit (m/type schema) schema children options)))] (m/walk s walk-fn options))) @@ -275,8 +322,7 @@ (mu/update-properties assoc ::root true)) options (into {::m/walk-entry-vals true - ::level 0 - ::max-level 300} + ::level 0} options)] (binding [*definitions* defs] diff --git a/common/src/app/common/schema/openapi.cljc b/common/src/app/common/schema/openapi.cljc index 967e267043..19ff8ca176 100644 --- a/common/src/app/common/schema/openapi.cljc +++ b/common/src/app/common/schema/openapi.cljc @@ -6,6 +6,8 @@ (ns app.common.schema.openapi (:require + [app.common.data :as d] + [app.common.schema :as-alias sm] [clojure.set :as set] [cuerdas.core :as str] [malli.core :as m])) @@ -15,16 +17,44 @@ (declare transform*) (defmulti visit (fn [name _schema _children _options] name) :default ::default) -(defmethod visit ::default [_ _ _ _] {}) + +(defmethod visit ::default [_ schema _ _] + (let [props (m/type-properties schema)] + (d/without-nils + {:type (get props ::type) + :format (get props ::format) + :title (get props :title) + :description (get props :description)}))) + (defmethod visit :> [_ _ [value] _] {:type "number" :exclusiveMinimum value}) (defmethod visit :>= [_ _ [value] _] {:type "number" :minimum value}) (defmethod visit :< [_ _ [value] _] {:type "number" :exclusiveMaximum value}) (defmethod visit :<= [_ _ [value] _] {:type "number" :maximum value}) -(defmethod visit := [_ _ [value] _] {:const value}) + +(defmethod visit := [_ schema children _] + (let [props (m/properties schema) + type (get props :type :string)] + (d/without-nils + {:type (or (get props ::type) + (d/name type)) + :enum (if (= :string type) + (mapv d/name children) + (vec children))}))) + + (defmethod visit :not= [_ _ _ _] {}) +(defmethod visit :fn [_ _ _ _] + nil) + +(defmethod visit ::sm/contains-any [_ _ _ _] + nil) + (defmethod visit :not [_ _ children _] {:not (last children)}) -(defmethod visit :and [_ _ children _] {:allOf children}) +(defmethod visit :and [_ _ children _] + {:allOf (keep not-empty children)}) + + (defmethod visit :or [_ _ children _] {:anyOf children}) (defmethod visit :orn [_ _ children _] {:anyOf (map last children)}) @@ -71,14 +101,28 @@ :minProperties :maxProperties)) -(defmethod visit :vector [_ schema children _] - (let [child (-> schema m/children first) - props (m/properties (m/deref child))] - (minmax-properties - {:type "array", :items (first children) :title (:title props)} - schema - :minItems - :maxItems))) +(defmethod visit :any [_ _ _ _] + {:description "Any Value"}) + +(defmethod visit ::sm/set [_ schema children _] + (minmax-properties + {:type "array", :items (first children), :uniqueItems true} + schema + :minItems + :maxItems)) + +(defmethod visit ::sm/vec [_ schema children _] + (minmax-properties + {:type "array", :items (first children)} + schema + :minItems + :maxItems)) + +(defmethod visit :vector [_ schema children options] + (visit ::sm/vec schema children options)) + +(defmethod visit :set [_ schema children options] + (visit ::sm/set schema children options)) (defmethod visit :sequential [_ schema children _] (minmax-properties @@ -87,36 +131,64 @@ :minItems :maxItems)) -(defmethod visit :set [_ schema children _] - (minmax-properties - {:type "array", :items (first children), :uniqueItems true} - schema - :minItems - :maxItems)) +(defmethod visit :enum [_ _ children options] + (merge (some-> (m/-infer children) (transform* options)) {:enum children})) + +(defmethod visit :maybe [_ _ children _] + (let [children (first children)] + (assoc children :nullable true))) + +(defmethod visit :tuple [_ _ children _] + {:type "array", :items children, :additionalItems false}) -(defmethod visit :enum [_ _ children options] (merge (some-> (m/-infer children) (transform* options)) {:enum children})) -(defmethod visit :maybe [_ _ children _] {:oneOf (conj children {:type "null"})}) -(defmethod visit :tuple [_ _ children _] {:type "array", :items children, :additionalItems false}) (defmethod visit :re [_ schema _ options] {:type "string", :pattern (str (first (m/children schema options)))}) + (defmethod visit :nil [_ _ _ _] {:type "null"}) (defmethod visit :string [_ schema _ _] (merge {:type "string"} (-> schema m/properties (select-keys [:min :max]) (set/rename-keys {:min :minLength, :max :maxLength})))) + +(defmethod visit ::sm/one-of [_ _ children _] + (let [options (->> (first children) + (mapv d/name))] + {:type "string" + :enum options})) + (defmethod visit :int [_ schema _ _] - (merge {:type "integer"} (-> schema m/properties (select-keys [:min :max]) (set/rename-keys {:min :minimum, :max :maximum})))) + (minmax-properties + {:type "integer"} + schema + :minimum + :maximum)) (defmethod visit :double [_ schema _ _] - (merge {:type "number"} - (-> schema m/properties (select-keys [:min :max]) (set/rename-keys {:min :minimum, :max :maximum})))) + (minmax-properties + {:type "number" + :format "double"} + schema + :minimum + :maximum)) + +(defmethod visit ::sm/int + [_ schema children options] + (visit :int schema children options)) + +(defmethod visit ::sm/double + [_ schema children options] + (visit :double schema children options)) (defmethod visit :boolean [_ _ _ _] {:type "boolean"}) +(defmethod visit ::sm/boolean [_ _ _ _] {:type "boolean"}) + + (defmethod visit :keyword [_ _ _ _] {:type "string"}) (defmethod visit :qualified-keyword [_ _ _ _] {:type "string"}) (defmethod visit :symbol [_ _ _ _] {:type "string"}) (defmethod visit :qualified-symbol [_ _ _ _] {:type "string"}) (defmethod visit :uuid [_ _ _ _] {:type "string" :format "uuid"}) +(defmethod visit ::sm/uuid [_ _ _ _] {:type "string" :format "uuid"}) (defmethod visit :schema [_ schema children options] (visit ::m/schema schema children options)) @@ -124,11 +196,14 @@ (defmethod visit ::m/schema [_ schema _ options] (let [result (transform* (m/deref schema) options) defpath (::definitions-path options "#/definitions/")] - (if-let [ref (m/-ref schema)] - (let [rkey (str/concat (str/camel (namespace ref)) "$" (name ref))] - (some-> *definitions* (swap! assoc rkey result)) - {"$ref" (str/concat defpath rkey)}) - result))) + + (if (::embed options) + result + (if-let [ref (m/-ref schema)] + (let [rkey (str/concat (str/camel (namespace ref)) "$" (name ref))] + (some-> *definitions* (swap! assoc rkey result)) + {"$ref" (str/concat defpath rkey)}) + result)))) (defmethod visit :merge [_ schema _ options] (transform* (m/deref schema) options)) (defmethod visit :union [_ schema _ options] (transform* (m/deref schema) options)) diff --git a/common/src/app/common/types/color.cljc b/common/src/app/common/types/color.cljc index cd8354eeec..e024ce28d3 100644 --- a/common/src/app/common/types/color.cljc +++ b/common/src/app/common/types/color.cljc @@ -60,16 +60,17 @@ {:type ::hex-color :pred hex-color-string? :type-properties - {:title "hex-color" + {:title "HexColor" :description "HEX Color String" :error/message "expected a valid HEX color" :error/code "errors.invalid-hex-color" :gen/gen hex-color-generator - ::oapi/type "integer" - ::oapi/format "int64"}})) + ::oapi/type "string" + ::oapi/format "rgb"}})) (def schema:plain-color - [:map [:color schema:hex-color]]) + [:map {:title "PlainColorAttrs"} + [:color schema:hex-color]]) (def schema:image [:map {:title "ImageColor" :closed true} @@ -85,7 +86,8 @@ (sm/keys schema:image)) (def schema:image-color - [:map [:image schema:image]]) + [:map {:title "ImageColorAttrs"} + [:image schema:image]]) (def gradient-types #{:linear :radial}) @@ -110,10 +112,11 @@ (sm/keys schema:gradient)) (def schema:gradient-color - [:map [:gradient schema:gradient]]) + [:map {:title "GradientColorAttrs"} + [:gradient schema:gradient]]) (def schema:color-attrs - [:map {:title "ColorAttrs" :closed true} + [:map {:title "GenericColorAttrs" :closed true} [:opacity {:optional true} [::sm/number {:min 0 :max 1}]] [:ref-id {:optional true} ::sm/uuid] [:ref-file {:optional true} ::sm/uuid]]) @@ -132,7 +135,7 @@ (into required-color-attrs (sm/keys schema:color-attrs))) (def schema:library-color-attrs - [:map {:title "ColorAttrs" :closed true} + [:map {:title "LibraryColorAttrs" :closed true} [:id ::sm/uuid] [:name ::sm/text] [:path {:optional true} :string] diff --git a/common/src/app/common/types/grid.cljc b/common/src/app/common/types/grid.cljc index 4b63a3cd8d..34e20435bd 100644 --- a/common/src/app/common/types/grid.cljc +++ b/common/src/app/common/types/grid.cljc @@ -14,12 +14,12 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (def schema:grid-color - [:map {:title "PageGridColor"} + [:map {:title "GridColor"} [:color clr/schema:hex-color] [:opacity ::sm/safe-number]]) (def schema:column-params - [:map + [:map {:title "ColumnGridParams"} [:color schema:grid-color] [:type {:optional true} [::sm/one-of #{:stretch :left :center :right}]] [:size {:optional true} [:maybe ::sm/safe-number]] @@ -28,7 +28,7 @@ [:gutter {:optional true} [:maybe ::sm/safe-number]]]) (def schema:square-params - [:map + [:map {:title "SquareGridParams"} [:size {:optional true} [:maybe ::sm/safe-number]] [:color schema:grid-color]]) @@ -37,19 +37,19 @@ :dispatch :type :decode/json #(update % :type keyword)} [:column - [:map + [:map {:title "ColumnGridAttrs"} [:type [:= :column]] [:display :boolean] [:params schema:column-params]]] [:row - [:map + [:map {:title "RowGridAttrs"} [:type [:= :row]] [:display :boolean] [:params schema:column-params]]] [:square - [:map + [:map {:title "SquareGridAttrs"} [:type [:= :square]] [:display :boolean] [:params schema:square-params]]]]) diff --git a/common/src/app/common/types/path/impl.cljc b/common/src/app/common/types/path/impl.cljc index bae9d4840d..0134e9abb1 100644 --- a/common/src/app/common/types/path/impl.cljc +++ b/common/src/app/common/types/path/impl.cljc @@ -18,6 +18,7 @@ [app.common.data.macros :as dm] [app.common.schema :as sm] [app.common.schema.generators :as sg] + [app.common.schema.openapi :as oapi] [app.common.svg.path :as svg.path] [app.common.transit :as t] [app.common.types.path :as-alias path] @@ -537,7 +538,8 @@ (sg/fmap from-plain))] {:pred path-data? :type-properties - {:gen/gen generator + {::oapi/type "string" + :gen/gen generator :encode/json identity :decode/json (fn [s] (cond diff --git a/common/src/app/common/types/plugins.cljc b/common/src/app/common/types/plugins.cljc index c4402591a9..d5a30712cb 100644 --- a/common/src/app/common/types/plugins.cljc +++ b/common/src/app/common/types/plugins.cljc @@ -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 diff --git a/common/src/app/common/types/shape.cljc b/common/src/app/common/types/shape.cljc index 29839fd9dc..3782010fd3 100644 --- a/common/src/app/common/types/shape.cljc +++ b/common/src/app/common/types/shape.cljc @@ -184,7 +184,7 @@ [:height ::sm/safe-number]]) (def schema:shape-generic-attrs - [:map {:title "ShapeAttrs"} + [:map {:title "ShapeGenericAttrs"} [:page-id {:optional true} ::sm/uuid] [:component-id {:optional true} ::sm/uuid] [:component-file {:optional true} ::sm/uuid] diff --git a/common/src/app/common/types/shape/interactions.cljc b/common/src/app/common/types/shape/interactions.cljc index 2547f5528a..c06b598a2b 100644 --- a/common/src/app/common/types/shape/interactions.cljc +++ b/common/src/app/common/types/shape/interactions.cljc @@ -109,8 +109,8 @@ (def check-animation! (sm/check-fn schema:animation)) -(def schema:interaction-attrs - [:map {:title "InteractionAttrs"} +(def schema:generic-interaction-attrs + [:map {:title "GenericInteractionAttrs"} [:action-type {:optional true} [::sm/one-of action-types]] [:event-type {:optional true} [::sm/one-of event-types]] [:destination {:optional true} [:maybe ::sm/uuid]] @@ -124,7 +124,7 @@ [:url {:optional true} :string]]) (def schema:navigate-interaction - [:map + [:map {:title "NavigateInteraction"} [:action-type [:= :navigate]] [:event-type [::sm/one-of event-types]] [:destination {:optional true} [:maybe ::sm/uuid]] @@ -132,7 +132,7 @@ [:animation {:optional true} schema:animation]]) (def schema:open-overlay-interaction - [:map + [:map {:title "OpenOverlayInteraction"} [:action-type [:= :open-overlay]] [:event-type [::sm/one-of event-types]] [:overlay-position ::gpt/point] @@ -144,7 +144,7 @@ [:position-relative-to {:optional true} [:maybe ::sm/uuid]]]) (def schema:toggle-overlay-interaction - [:map + [:map {:title "ToggleOverlayInteraction"} [:action-type [:= :toggle-overlay]] [:event-type [::sm/one-of event-types]] [:overlay-position ::gpt/point] @@ -156,7 +156,7 @@ [:position-relative-to {:optional true} [:maybe ::sm/uuid]]]) (def schema:close-overlay-interaction - [:map + [:map {:title "CloseOverlayInteraction"} [:action-type [:= :close-overlay]] [:event-type [::sm/one-of event-types]] [:destination {:optional true} [:maybe ::sm/uuid]] @@ -164,32 +164,33 @@ [:position-relative-to {:optional true} [:maybe ::sm/uuid]]]) (def schema:prev-scren-interaction - [:map + [:map {:title "PrevScreenInteraction"} [:action-type [:= :prev-screen]] [:event-type [::sm/one-of event-types]]]) (def schema:open-url-interaction - [:map + [:map {:title "OpenUrlInteraction"} [:action-type [:= :open-url]] [:event-type [::sm/one-of event-types]] [: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:generic-interaction-attrs + [:multi {:dispatch :action-type :title "InteractionAttrs"} + [: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) diff --git a/common/src/app/common/types/shape/shadow.cljc b/common/src/app/common/types/shape/shadow.cljc index ef44bc4a74..32545336cd 100644 --- a/common/src/app/common/types/shape/shadow.cljc +++ b/common/src/app/common/types/shape/shadow.cljc @@ -7,7 +7,6 @@ (ns app.common.types.shape.shadow (:require [app.common.schema :as sm] - [app.common.schema.generators :as sg] [app.common.types.color :as ctc])) (def styles #{:drop-shadow :inner-shadow}) @@ -15,10 +14,7 @@ (def schema:shadow [:map {:title "Shadow"} [:id [:maybe ::sm/uuid]] - [:style - [:and {:gen/gen (sg/elements styles)} - :keyword - [::sm/one-of styles]]] + [:style [::sm/one-of styles]] [:offset-x ::sm/safe-number] [:offset-y ::sm/safe-number] [:blur ::sm/safe-number] diff --git a/common/src/app/common/types/token.cljc b/common/src/app/common/types/token.cljc index 4cc143eed2..de918cb610 100644 --- a/common/src/app/common/types/token.cljc +++ b/common/src/app/common/types/token.cljc @@ -8,6 +8,7 @@ (:require [app.common.data :as d] [app.common.schema :as sm] + [app.common.schema.generators :as sg] [clojure.data :as data] [clojure.set :as set] [cuerdas.core :as str] @@ -56,7 +57,8 @@ (into #{} (keys token-type->dtcg-token-type))) (def token-name-ref - [:and :string [:re #"^(?!\$)([a-zA-Z0-9-$_]+\.?)*(? (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)) @@ -140,22 +144,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)) @@ -197,8 +199,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)) @@ -215,10 +218,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 From d7c19325cc4ae2f3a91510c7f1a72d7e13f2df46 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 19 Aug 2025 20:51:19 +0200 Subject: [PATCH 10/11] :sparkles: Add better type references naming on openapi output --- common/src/app/common/schema/openapi.cljc | 29 ++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/common/src/app/common/schema/openapi.cljc b/common/src/app/common/schema/openapi.cljc index 19ff8ca176..33e8b2561d 100644 --- a/common/src/app/common/schema/openapi.cljc +++ b/common/src/app/common/schema/openapi.cljc @@ -200,7 +200,34 @@ (if (::embed options) result (if-let [ref (m/-ref schema)] - (let [rkey (str/concat (str/camel (namespace ref)) "$" (name ref))] + (let [nname (namespace ref) + tname (name ref) + tname (str/capital (str/camel tname)) + + nname (cond + (or (= nname "app.common.schema") + (= nname "app.common.time") + (= nname "app.common.features")) + "" + + (= nname "datoteka.fs") + "Filesystem" + + (str/starts-with? nname "app.common.geom") + (-> (str/replace nname #"app\.common\.geom\.\w+" "geom") + (str/camel) + (str/capital)) + + (str/starts-with? nname "app.") + (-> (subs nname 4) + (str/camel) + (str/capital)) + + :else + (str/capital (str/camel nname))) + + rkey (str nname tname)] + (some-> *definitions* (swap! assoc rkey result)) {"$ref" (str/concat defpath rkey)}) result)))) From 575342b3bb8df28e33db4c58c50e1cc09fafa97d Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 20 Aug 2025 09:36:49 +0200 Subject: [PATCH 11/11] :recycle: Use direct schemas instead of references Only a very common use, basic types schemas should be used as reference (with namespaced keywords) --- backend/src/app/binfile/v3.clj | 38 +++++++++--------- backend/src/app/media.clj | 16 ++++---- backend/src/app/rpc/commands/binfile.clj | 2 +- backend/src/app/rpc/commands/files.clj | 2 +- backend/src/app/rpc/commands/files_temp.clj | 3 +- .../src/app/rpc/commands/files_thumbnails.clj | 4 +- backend/src/app/rpc/commands/files_update.clj | 6 +-- backend/src/app/rpc/commands/media.clj | 2 +- backend/src/app/rpc/commands/profile.clj | 2 +- backend/src/app/rpc/commands/teams.clj | 10 ++--- .../app/rpc/commands/teams_invitations.clj | 8 ++-- backend/src/app/rpc/commands/verify_token.clj | 2 +- backend/src/app/rpc/permissions.clj | 17 ++++---- .../backend_tests/util_objects_map_test.clj | 6 +-- common/src/app/common/files/changes.cljc | 17 ++++---- .../src/app/common/files/changes_builder.cljc | 9 ++--- common/src/app/common/types/color.cljc | 2 +- common/src/app/common/types/component.cljc | 24 +++++------ common/src/app/common/types/file.cljc | 1 - common/src/app/common/types/grid.cljc | 11 ++--- common/src/app/common/types/page.cljc | 7 +--- common/src/app/common/types/plugins.cljc | 16 +++----- common/src/app/common/types/shape.cljc | 37 ++++++++--------- common/src/app/common/types/shape/blur.cljc | 33 ++++----------- common/src/app/common/types/shape/export.cljc | 2 - .../app/common/types/shape/interactions.cljc | 2 - common/src/app/common/types/shape/text.cljc | 40 ++++++++----------- common/src/app/common/types/team.cljc | 3 +- common/src/app/common/types/tokens_lib.cljc | 2 +- common/src/app/common/types/typography.cljc | 34 ++++++++-------- common/src/app/common/types/variant.cljc | 21 ++++------ .../types/shape_decode_encode_test.cljc | 8 ++-- frontend/src/app/main/data/changes.cljs | 11 ++--- .../app/main/data/workspace/libraries.cljs | 10 ++--- .../main/data/workspace/notifications.cljs | 16 ++++---- .../src/app/main/data/workspace/undo.cljs | 4 +- frontend/src/app/plugins/shape.cljs | 10 ++--- library/src/lib/export.cljs | 2 +- 38 files changed, 182 insertions(+), 258 deletions(-) diff --git a/backend/src/app/binfile/v3.clj b/backend/src/app/binfile/v3.clj index e8c9f8265f..f66a4da539 100644 --- a/backend/src/app/binfile/v3.clj +++ b/backend/src/app/binfile/v3.clj @@ -103,25 +103,25 @@ (sm/encoder ctp/schema:page sm/json-transformer)) (def encode-shape - (sm/encoder ::cts/shape sm/json-transformer)) + (sm/encoder cts/schema:shape sm/json-transformer)) (def encode-media - (sm/encoder ::ctf/media sm/json-transformer)) + (sm/encoder ctf/schema:media sm/json-transformer)) (def encode-component - (sm/encoder ::ctc/component sm/json-transformer)) + (sm/encoder ctc/schema:component sm/json-transformer)) (def encode-color (sm/encoder ctcl/schema:library-color sm/json-transformer)) (def encode-typography - (sm/encoder ::cty/typography sm/json-transformer)) + (sm/encoder cty/schema:typography sm/json-transformer)) (def encode-tokens-lib - (sm/encoder ::cto/tokens-lib sm/json-transformer)) + (sm/encoder cto/schema:tokens-lib sm/json-transformer)) (def encode-plugin-data - (sm/encoder ::ctpg/plugin-data sm/json-transformer)) + (sm/encoder ctpg/schema:plugin-data sm/json-transformer)) (def encode-storage-object (sm/encoder schema:storage-object sm/json-transformer)) @@ -138,7 +138,7 @@ (sm/decoder ctf/schema:media sm/json-transformer)) (def decode-component - (sm/decoder ::ctc/component sm/json-transformer)) + (sm/decoder ctc/schema:component sm/json-transformer)) (def decode-color (sm/decoder ctcl/schema:library-color sm/json-transformer)) @@ -147,19 +147,19 @@ (sm/decoder schema:file sm/json-transformer)) (def decode-page - (sm/decoder ::ctp/page sm/json-transformer)) + (sm/decoder ctp/schema:page sm/json-transformer)) (def decode-shape - (sm/decoder ::cts/shape sm/json-transformer)) + (sm/decoder cts/schema:shape sm/json-transformer)) (def decode-typography - (sm/decoder ::cty/typography sm/json-transformer)) + (sm/decoder cty/schema:typography sm/json-transformer)) (def decode-tokens-lib (sm/decoder cto/schema:tokens-lib sm/json-transformer)) (def decode-plugin-data - (sm/decoder ::ctpg/plugin-data sm/json-transformer)) + (sm/decoder ctpg/schema:plugin-data sm/json-transformer)) (def decode-storage-object (sm/decoder schema:storage-object sm/json-transformer)) @@ -173,31 +173,31 @@ (sm/check-fn schema:manifest)) (def validate-file - (sm/check-fn ::ctf/file)) + (sm/check-fn ctf/schema:file)) (def validate-page - (sm/check-fn ::ctp/page)) + (sm/check-fn ctp/schema:page)) (def validate-shape - (sm/check-fn ::cts/shape)) + (sm/check-fn cts/schema:shape)) (def validate-media - (sm/check-fn ::ctf/media)) + (sm/check-fn ctf/schema:media)) (def validate-color (sm/check-fn ctcl/schema:library-color)) (def validate-component - (sm/check-fn ::ctc/component)) + (sm/check-fn ctc/schema:component)) (def validate-typography - (sm/check-fn ::cty/typography)) + (sm/check-fn cty/schema:typography)) (def validate-tokens-lib - (sm/check-fn ::cto/tokens-lib)) + (sm/check-fn cto/schema:tokens-lib)) (def validate-plugin-data - (sm/check-fn ::ctpg/plugin-data)) + (sm/check-fn ctpg/schema:plugin-data)) (def validate-storage-object (sm/check-fn schema:storage-object)) diff --git a/backend/src/app/media.clj b/backend/src/app/media.clj index fafcccd2dc..52f89668b1 100644 --- a/backend/src/app/media.clj +++ b/backend/src/app/media.clj @@ -38,15 +38,13 @@ org.im4java.core.Info)) (def schema:upload - (sm/register! - ^{::sm/type ::upload} - [:map {:title "Upload"} - [:filename :string] - [:size ::sm/int] - [:path ::fs/path] - [:mtype {:optional true} :string] - [:headers {:optional true} - [:map-of :string :string]]])) + [:map {:title "Upload"} + [:filename :string] + [:size ::sm/int] + [:path ::fs/path] + [:mtype {:optional true} :string] + [:headers {:optional true} + [:map-of :string :string]]]) (def ^:private schema:input [:map {:title "Input"} diff --git a/backend/src/app/rpc/commands/binfile.clj b/backend/src/app/rpc/commands/binfile.clj index bb53109bac..c9542d4089 100644 --- a/backend/src/app/rpc/commands/binfile.clj +++ b/backend/src/app/rpc/commands/binfile.clj @@ -127,7 +127,7 @@ [:project-id ::sm/uuid] [:file-id {:optional true} ::sm/uuid] [:version {:optional true} ::sm/int] - [:file ::media/upload]]) + [:file media/schema:upload]]) (sv/defmethod ::import-binfile "Import a penpot file in a binary format. If `file-id` is provided, diff --git a/backend/src/app/rpc/commands/files.clj b/backend/src/app/rpc/commands/files.clj index 8916b74d9a..38a518856e 100644 --- a/backend/src/app/rpc/commands/files.clj +++ b/backend/src/app/rpc/commands/files.clj @@ -195,7 +195,7 @@ (def schema:permissions-mixin [:map {:title "PermissionsMixin"} - [:permissions ::perms/permissions]]) + [:permissions perms/schema:permissions]]) (def schema:file-with-permissions [:merge {:title "FileWithPermissions"} diff --git a/backend/src/app/rpc/commands/files_temp.clj b/backend/src/app/rpc/commands/files_temp.clj index ca3b107a0b..5446505d0c 100644 --- a/backend/src/app/rpc/commands/files_temp.clj +++ b/backend/src/app/rpc/commands/files_temp.clj @@ -79,10 +79,9 @@ ;; --- MUTATION COMMAND: update-temp-file - (def ^:private schema:update-temp-file [:map {:title "update-temp-file"} - [:changes [:vector ::cpc/change]] + [:changes [:vector cpc/schema:change]] [:revn [::sm/int {:min 0}]] [:session-id ::sm/uuid] [:id ::sm/uuid]]) diff --git a/backend/src/app/rpc/commands/files_thumbnails.clj b/backend/src/app/rpc/commands/files_thumbnails.clj index 3acac54d46..af5b62e6b6 100644 --- a/backend/src/app/rpc/commands/files_thumbnails.clj +++ b/backend/src/app/rpc/commands/files_thumbnails.clj @@ -271,7 +271,7 @@ [:map {:title "create-file-object-thumbnail"} [:file-id ::sm/uuid] [:object-id [:string {:max 250}]] - [:media ::media/upload] + [:media media/schema:upload] [:tag {:optional true} [:string {:max 50}]]]) (sv/defmethod ::create-file-object-thumbnail @@ -381,7 +381,7 @@ [:map {:title "create-file-thumbnail"} [:file-id ::sm/uuid] [:revn ::sm/int] - [:media ::media/upload]]) + [:media media/schema:upload]]) (sv/defmethod ::create-file-thumbnail "Creates or updates the file thumbnail. Mainly used for paint the diff --git a/backend/src/app/rpc/commands/files_update.clj b/backend/src/app/rpc/commands/files_update.clj index 9dcbf8ec94..9d52b7a2c4 100644 --- a/backend/src/app/rpc/commands/files_update.clj +++ b/backend/src/app/rpc/commands/files_update.clj @@ -64,10 +64,10 @@ [:revn {:min 0} ::sm/int] [:vern {:min 0} ::sm/int] [:features {:optional true} ::cfeat/features] - [:changes {:optional true} [:vector ::cpc/change]] + [:changes {:optional true} [:vector cpc/schema:change]] [:changes-with-metadata {:optional true} [:vector [:map - [:changes [:vector ::cpc/change]] + [:changes [:vector cpc/schema:change]] [:hint-origin {:optional true} :keyword] [:hint-events {:optional true} [:vector [:string {:max 250}]]]]]] [:skip-validate {:optional true} ::sm/boolean]]) @@ -76,7 +76,7 @@ schema:update-file-result [:vector {:title "update-file-result"} [:map - [:changes [:vector ::cpc/change]] + [:changes [:vector cpc/schema:change]] [:file-id ::sm/uuid] [:id ::sm/uuid] [:revn {:min 0} ::sm/int] diff --git a/backend/src/app/rpc/commands/media.clj b/backend/src/app/rpc/commands/media.clj index 042053a2b1..5fa70e9837 100644 --- a/backend/src/app/rpc/commands/media.clj +++ b/backend/src/app/rpc/commands/media.clj @@ -48,7 +48,7 @@ [:file-id ::sm/uuid] [:is-local ::sm/boolean] [:name [:string {:max 250}]] - [:content ::media/upload]]) + [:content media/schema:upload]]) (sv/defmethod ::upload-file-media-object {::doc/added "1.17" diff --git a/backend/src/app/rpc/commands/profile.clj b/backend/src/app/rpc/commands/profile.clj index 9425e009f1..292cb9467d 100644 --- a/backend/src/app/rpc/commands/profile.clj +++ b/backend/src/app/rpc/commands/profile.clj @@ -253,7 +253,7 @@ (def ^:private schema:update-profile-photo [:map {:title "update-profile-photo"} - [:file ::media/upload]]) + [:file media/schema:upload]]) (sv/defmethod ::update-profile-photo {:doc/added "1.1" diff --git a/backend/src/app/rpc/commands/teams.clj b/backend/src/app/rpc/commands/teams.clj index 4f2e236dd7..1c65e8e516 100644 --- a/backend/src/app/rpc/commands/teams.clj +++ b/backend/src/app/rpc/commands/teams.clj @@ -12,7 +12,7 @@ [app.common.features :as cfeat] [app.common.schema :as sm] [app.common.time :as ct] - [app.common.types.team :as tt] + [app.common.types.team :as types.team] [app.common.uuid :as uuid] [app.config :as cf] [app.db :as db] @@ -629,7 +629,7 @@ ;; assign owner role to new profile (db/update! conn :team-profile-rel - (get tt/permissions-for-role :owner) + (get types.team/permissions-for-role :owner) {:team-id id :profile-id reassign-to})) ;; and finally, if all other conditions does not match and the @@ -742,7 +742,7 @@ :team-id team-id :role role}) - (let [params (get tt/permissions-for-role role)] + (let [params (get types.team/permissions-for-role role)] ;; Only allow single owner on team (when (= role :owner) (db/update! conn :team-profile-rel @@ -760,7 +760,7 @@ [:map {:title "update-team-member-role"} [:team-id ::sm/uuid] [:member-id ::sm/uuid] - [:role ::tt/role]]) + [:role types.team/schema:role]]) (sv/defmethod ::update-team-member-role {::doc/added "1.17" @@ -810,7 +810,7 @@ (def ^:private schema:update-team-photo [:map {:title "update-team-photo"} [:team-id ::sm/uuid] - [:file ::media/upload]]) + [:file media/schema:upload]]) (sv/defmethod ::update-team-photo {::doc/added "1.17" diff --git a/backend/src/app/rpc/commands/teams_invitations.clj b/backend/src/app/rpc/commands/teams_invitations.clj index 6d92b25d87..3559a3e7ed 100644 --- a/backend/src/app/rpc/commands/teams_invitations.clj +++ b/backend/src/app/rpc/commands/teams_invitations.clj @@ -75,7 +75,7 @@ [:map [:id ::sm/uuid] [:fullname :string]]] - [:role ::types.team/role] + [:role types.team/schema:role] [:email ::sm/email]]) (def ^:private check-create-invitation-params @@ -257,7 +257,7 @@ (def ^:private schema:create-team-invitations [:map {:title "create-team-invitations"} [:team-id ::sm/uuid] - [:role ::types.team/role] + [:role types.team/schema:role] [:emails [::sm/set ::sm/email]]]) (def ^:private max-invitations-by-request-threshold @@ -318,7 +318,7 @@ [:features {:optional true} ::cfeat/features] [:id {:optional true} ::sm/uuid] [:emails [::sm/set ::sm/email]] - [:role ::types.team/role]]) + [:role types.team/schema:role]]) (sv/defmethod ::create-team-with-invitations {::doc/added "1.17" @@ -403,7 +403,7 @@ [:map {:title "update-team-invitation-role"} [:team-id ::sm/uuid] [:email ::sm/email] - [:role ::types.team/role]]) + [:role types.team/schema:role]]) (sv/defmethod ::update-team-invitation-role {::doc/added "1.17" diff --git a/backend/src/app/rpc/commands/verify_token.clj b/backend/src/app/rpc/commands/verify_token.clj index afab9a10c4..ff59a5eead 100644 --- a/backend/src/app/rpc/commands/verify_token.clj +++ b/backend/src/app/rpc/commands/verify_token.clj @@ -128,7 +128,7 @@ [:iss :keyword] [:exp ::ct/inst] [:profile-id ::sm/uuid] - [:role ::types.team/role] + [:role types.team/schema:role] [:team-id ::sm/uuid] [:member-email ::sm/email] [:member-id {:optional true} ::sm/uuid]]) diff --git a/backend/src/app/rpc/permissions.clj b/backend/src/app/rpc/permissions.clj index e1411a9816..e18b09cad2 100644 --- a/backend/src/app/rpc/permissions.clj +++ b/backend/src/app/rpc/permissions.clj @@ -10,15 +10,14 @@ [app.common.exceptions :as ex] [app.common.schema :as sm])) -(sm/register! - ^{::sm/type ::permissions} - [:map {:title "Permissions"} - [:type {:gen/elements [:membership :share-link]} :keyword] - [:is-owner ::sm/boolean] - [:is-admin ::sm/boolean] - [:can-edit ::sm/boolean] - [:can-read ::sm/boolean] - [:is-logged ::sm/boolean]]) +(def schema:permissions + [:map {:title "Permissions"} + [:type {:gen/elements [:membership :share-link]} :keyword] + [:is-owner ::sm/boolean] + [:is-admin ::sm/boolean] + [:can-edit ::sm/boolean] + [:can-read ::sm/boolean] + [:is-logged ::sm/boolean]]) (def valid-roles #{:admin :owner :editor :viewer}) diff --git a/backend/test/backend_tests/util_objects_map_test.clj b/backend/test/backend_tests/util_objects_map_test.clj index 56c589f6b8..d04edb60d4 100644 --- a/backend/test/backend_tests/util_objects_map_test.clj +++ b/backend/test/backend_tests/util_objects_map_test.clj @@ -86,7 +86,7 @@ (t/deftest internal-encode-decode (smt/check! - (smt/for [data (->> (cg/map cg/uuid (sg/generator ::cts/shape)) + (smt/for [data (->> (cg/map cg/uuid (sg/generator cts/schema:shape)) (cg/not-empty))] (let [obj1 (omap/wrap data) obj2 (omap/create (deref obj1)) @@ -103,7 +103,7 @@ (t/deftest fressian-encode-decode (smt/check! - (smt/for [data (->> (cg/map cg/uuid (sg/generator ::cts/shape)) + (smt/for [data (->> (cg/map cg/uuid (sg/generator cts/schema:shape)) (cg/not-empty) (cg/fmap omap/wrap) (cg/fmap (fn [o] {:objects o})))] @@ -119,7 +119,7 @@ (t/deftest transit-encode-decode (smt/check! - (smt/for [data (->> (cg/map cg/uuid (sg/generator ::cts/shape)) + (smt/for [data (->> (cg/map cg/uuid (sg/generator cts/schema:shape)) (cg/not-empty) (cg/fmap omap/wrap) (cg/fmap (fn [o] {:objects o})))] diff --git a/common/src/app/common/files/changes.cljc b/common/src/app/common/files/changes.cljc index e0ff3917a5..73f48f5661 100644 --- a/common/src/app/common/files/changes.cljc +++ b/common/src/app/common/files/changes.cljc @@ -112,7 +112,7 @@ [:type [:= :set-guide]] [:page-id ::sm/uuid] [:id ::sm/uuid] - [:params [:maybe ::ctp/guide]]] + [:params [:maybe ctp/schema:guide]]] gen (->> (sg/generator schema) (sg/fmap (fn [change] (if (some? (:params change)) @@ -125,7 +125,7 @@ [:type [:= :set-flow]] [:page-id ::sm/uuid] [:id ::sm/uuid] - [:params [:maybe ::ctp/flow]]] + [:params [:maybe ctp/schema:flow]]] gen (->> (sg/generator schema) (sg/fmap (fn [change] @@ -329,7 +329,7 @@ [:shapes {:optional true} [:vector {:gen/max 3} ::sm/any]] [:name {:optional true} :string] [:variant-id {:optional true} ::sm/uuid] - [:variant-properties {:optional true} [:vector ::ctv/variant-property]]]] + [:variant-properties {:optional true} [:vector ctv/schema:variant-property]]]] [:del-component [:map {:title "DelComponentChange"} @@ -354,12 +354,12 @@ [:add-typography [:map {:title "AddTypogrphyChange"} [:type [:= :add-typography]] - [:typography ::ctt/typography]]] + [:typography ctt/schema:typography]]] [:mod-typography [:map {:title "ModTypogrphyChange"} [:type [:= :mod-typography]] - [:typography ::ctt/typography]]] + [:typography ctt/schema:typography]]] [:del-typography [:map {:title "DelTypogrphyChange"} @@ -434,13 +434,10 @@ (def schema:changes [:sequential {:gen/max 5 :gen/min 1} schema:change]) -(sm/register! ::change schema:change) -(sm/register! ::changes schema:changes) - (def valid-change? (sm/lazy-validator schema:change)) -(def check-changes! +(def check-changes (sm/check-fn schema:changes)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -525,7 +522,7 @@ ;; When verify? false we spec the schema validation. Currently used ;; to make just 1 validation even if the changes are applied twice (when verify? - (check-changes! items)) + (check-changes items)) (binding [*touched-changes* (volatile! #{}) cts/*wasm-sync* true] diff --git a/common/src/app/common/files/changes_builder.cljc b/common/src/app/common/files/changes_builder.cljc index eab1df7f5b..473bcf5bef 100644 --- a/common/src/app/common/files/changes_builder.cljc +++ b/common/src/app/common/files/changes_builder.cljc @@ -24,7 +24,7 @@ [app.common.uuid :as uuid])) ;; Auxiliary functions to help create a set of changes (undo + redo) - +;; TODO: this is a duplicate schema (def schema:changes (sm/register! ^{::sm/type ::changes} @@ -36,7 +36,7 @@ [:stack-undo? {:optional true} boolean?] [:undo-group {:optional true} ::sm/any]])) -(def check-changes! +(def check-changes (sm/check-fn schema:changes)) (defn empty-changes @@ -168,9 +168,8 @@ (defn apply-changes-local [changes & {:keys [apply-to-library?]}] - (assert - (check-changes! changes) - "expected valid changes") + (assert (check-changes changes) + "expected valid changes") (if-let [file-data (::file-data (meta changes))] (let [library-data (::library-data (meta changes)) diff --git a/common/src/app/common/types/color.cljc b/common/src/app/common/types/color.cljc index e024ce28d3..c4532c4ac0 100644 --- a/common/src/app/common/types/color.cljc +++ b/common/src/app/common/types/color.cljc @@ -141,7 +141,7 @@ [:path {:optional true} :string] [:opacity {:optional true} [::sm/number {:min 0 :max 1}]] [:modified-at {:optional true} ::ct/inst] - [:plugin-data {:optional true} ::ctpg/plugin-data]]) + [:plugin-data {:optional true} ctpg/schema:plugin-data]]) (def schema:library-color "Used for in-transit representation of a color (per example when user diff --git a/common/src/app/common/types/component.cljc b/common/src/app/common/types/component.cljc index 24408f2133..a97c1d3b78 100644 --- a/common/src/app/common/types/component.cljc +++ b/common/src/app/common/types/component.cljc @@ -19,19 +19,17 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (def schema:component - (sm/register! - ^{::sm/type ::component} - [:merge - [:map - [:id ::sm/uuid] - [:name :string] - [:path {:optional true} [:maybe :string]] - [:modified-at {:optional true} ::ct/inst] - [:objects {:gen/max 10 :optional true} ctp/schema:objects] - [:main-instance-id ::sm/uuid] - [:main-instance-page ::sm/uuid] - [:plugin-data {:optional true} ctpg/schema:plugin-data]] - ctv/schema:variant-component])) + [:merge + [:map + [:id ::sm/uuid] + [:name :string] + [:path {:optional true} [:maybe :string]] + [:modified-at {:optional true} ::ct/inst] + [:objects {:gen/max 10 :optional true} ctp/schema:objects] + [:main-instance-id ::sm/uuid] + [:main-instance-page ::sm/uuid] + [:plugin-data {:optional true} ctpg/schema:plugin-data]] + ctv/schema:variant-component]) (def check-component (sm/check-fn schema:component)) diff --git a/common/src/app/common/types/file.cljc b/common/src/app/common/types/file.cljc index a49bc22df9..f7ee4c06de 100644 --- a/common/src/app/common/types/file.cljc +++ b/common/src/app/common/types/file.cljc @@ -110,7 +110,6 @@ (sm/register! ::data schema:data) (sm/register! ::file schema:file) -(sm/register! ::media schema:media) (sm/register! ::colors schema:colors) (sm/register! ::typographies schema:typographies) diff --git a/common/src/app/common/types/grid.cljc b/common/src/app/common/types/grid.cljc index 34e20435bd..caea01d210 100644 --- a/common/src/app/common/types/grid.cljc +++ b/common/src/app/common/types/grid.cljc @@ -56,14 +56,9 @@ (def schema:default-grids [:map {:title "PageGrid"} - [:square {:optional true} ::square-params] - [:row {:optional true} ::column-params] - [:column {:optional true} ::column-params]]) - -(sm/register! ::square-params schema:square-params) -(sm/register! ::column-params schema:column-params) -(sm/register! ::grid schema:grid) -(sm/register! ::default-grids schema:default-grids) + [:square {:optional true} schema:square-params] + [:row {:optional true} schema:column-params] + [:column {:optional true} schema:column-params]]) (def ^:private default-square-params {:size 16 diff --git a/common/src/app/common/types/page.cljc b/common/src/app/common/types/page.cljc index ee6084bd66..0d4041aaa0 100644 --- a/common/src/app/common/types/page.cljc +++ b/common/src/app/common/types/page.cljc @@ -40,7 +40,7 @@ [:map-of {:gen/max 2} ::sm/uuid schema:guide]) (def schema:objects - [:map-of {:gen/max 5} ::sm/uuid ::cts/shape]) + [:map-of {:gen/max 5} ::sm/uuid cts/schema:shape]) (def schema:comment-thread-position [:map {:title "CommentThreadPosition"} @@ -62,11 +62,6 @@ [:comment-thread-positions {:optional true} [:map-of ::sm/uuid schema:comment-thread-position]]]) -(sm/register! ::objects schema:objects) -(sm/register! ::page schema:page) -(sm/register! ::guide schema:guide) -(sm/register! ::flow schema:flow) - (def valid-guide? (sm/lazy-validator schema:guide)) diff --git a/common/src/app/common/types/plugins.cljc b/common/src/app/common/types/plugins.cljc index d5a30712cb..b582da3583 100644 --- a/common/src/app/common/types/plugins.cljc +++ b/common/src/app/common/types/plugins.cljc @@ -6,7 +6,6 @@ (ns app.common.types.plugins (:require - [app.common.schema :as sm] [app.common.schema.generators :as sg])) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -22,13 +21,11 @@ :keyword]) (def schema:plugin-data - (sm/register! - ^{::sm/type ::plugin-data} - [:map-of {:gen/max 5 :title "PluginsData"} - schema:keyword - [:map-of {:gen/max 5} - schema:string - schema:string]])) + [:map-of {:gen/max 5 :title "PluginsData"} + schema:keyword + [:map-of {:gen/max 5} + schema:string + schema:string]]) (def ^:private schema:registry-entry [:map @@ -47,6 +44,3 @@ [:map-of {:gen/max 5} :string schema:registry-entry]]]) - -(sm/register! ::plugin-registry schema:plugin-registry) -(sm/register! ::registry-entry schema:registry-entry) diff --git a/common/src/app/common/types/shape.cljc b/common/src/app/common/types/shape.cljc index 3782010fd3..d9e36f1105 100644 --- a/common/src/app/common/types/shape.cljc +++ b/common/src/app/common/types/shape.cljc @@ -119,8 +119,6 @@ (def schema:points [:vector {:gen/max 4 :gen/min 4} ::gpt/point]) -;; FIXME: the register is necessary until this is moved to a separated -;; ns because it is used on shapes.text (def valid-stroke-attrs "A set used for proper check if color should contain only one of the attrs listed in this set." @@ -156,10 +154,8 @@ (sm/keys schema:stroke-attrs)) (def schema:stroke - (sm/register! - ^{::sm/type ::stroke} - [:and schema:stroke-attrs - [:fn has-valid-stroke-attrs?]])) + [:and schema:stroke-attrs + [:fn has-valid-stroke-attrs?]]) (def check-stroke (sm/check-fn schema:stroke)) @@ -213,22 +209,22 @@ [:r4 {:optional true} ::sm/safe-number] [:opacity {:optional true} ::sm/safe-number] [:grids {:optional true} - [:vector {:gen/max 2} ::ctg/grid]] + [:vector {:gen/max 2} ctg/schema:grid]] [:exports {:optional true} - [:vector {:gen/max 2} ::ctse/export]] + [:vector {:gen/max 2} ctse/schema: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]] + [:vector {:gen/max 2} ctsi/schema:interaction]] [:shadow {:optional true} [:vector {:gen/max 1} ctss/schema:shadow]] - [:blur {:optional true} ::ctsb/blur] + [:blur {:optional true} ctsb/schema:blur] [:grow-type {:optional true} [::sm/one-of grow-types]] [:applied-tokens {:optional true} cto/schema:applied-tokens] - [:plugin-data {:optional true} ::ctpg/plugin-data]]) + [:plugin-data {:optional true} ctpg/schema:plugin-data]]) (def schema:group-attrs [:map {:title "GroupAttrs"} @@ -274,7 +270,8 @@ (def ^:private schema:text-attrs [:map {:title "TextAttrs"} - [:content {:optional true} [:maybe ::ctsx/content]]]) + [:position-data {:optional true} [:maybe ctsx/schema:position-data]] + [:content {:optional true} [:maybe ctsx/schema:content]]]) (defn- decode-shape [o] @@ -326,8 +323,8 @@ schema:shape-generic-attrs schema:shape-geom-attrs schema:shape-base-attrs - ::ctv/variant-shape - ::ctv/variant-container]] + ctv/schema:variant-shape + ctv/schema:variant-container]] [:bool [:merge {:title "BoolShape"} @@ -384,13 +381,11 @@ schema:shape-base-attrs]]]) (def schema:shape - (sm/register! - ^{::sm/type ::shape} - [:and {:title "Shape" - :gen/gen (shape-generator) - :decode/json {:leave decode-shape}} - [:fn shape?] - schema:shape-attrs])) + [:and {:title "Shape" + :gen/gen (shape-generator) + :decode/json {:leave decode-shape}} + [:fn shape?] + schema:shape-attrs]) (def check-shape-generic-attrs (sm/check-fn schema:shape-generic-attrs)) diff --git a/common/src/app/common/types/shape/blur.cljc b/common/src/app/common/types/shape/blur.cljc index 1b319502f8..3627ce0e67 100644 --- a/common/src/app/common/types/shape/blur.cljc +++ b/common/src/app/common/types/shape/blur.cljc @@ -6,30 +6,11 @@ (ns app.common.types.shape.blur (:require - [app.common.schema :as sm] - [app.common.spec :as us] - [clojure.spec.alpha :as s])) + [app.common.schema :as sm])) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; SPEC -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(s/def ::id uuid?) -(s/def ::type #{:layer-blur}) -(s/def ::value ::us/safe-number) -(s/def ::hidden boolean?) - -(s/def ::blur - (s/keys :req-un [::id ::type ::value ::hidden])) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; SCHEMA -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(sm/register! - ^{::sm/type ::blur} - [:map {:title "Blur"} - [:id ::sm/uuid] - [:type [:= :layer-blur]] - [:value ::sm/safe-number] - [:hidden :boolean]]) +(def schema:blur + [:map {:title "Blur"} + [:id ::sm/uuid] + [:type [:= :layer-blur]] + [:value ::sm/safe-number] + [:hidden :boolean]]) diff --git a/common/src/app/common/types/shape/export.cljc b/common/src/app/common/types/shape/export.cljc index feb7f8dec6..64134c361b 100644 --- a/common/src/app/common/types/shape/export.cljc +++ b/common/src/app/common/types/shape/export.cljc @@ -15,5 +15,3 @@ [:type [::sm/one-of types]] [:scale ::sm/safe-number] [:suffix :string]]) - -(sm/register! ::export schema:export) diff --git a/common/src/app/common/types/shape/interactions.cljc b/common/src/app/common/types/shape/interactions.cljc index c06b598a2b..8dd4ea457c 100644 --- a/common/src/app/common/types/shape/interactions.cljc +++ b/common/src/app/common/types/shape/interactions.cljc @@ -192,8 +192,6 @@ [:prev-screen schema:prev-scren-interaction] [:open-url schema:open-url-interaction]]]]) -(sm/register! ::interaction schema:interaction) - (def check-interaction (sm/check-fn schema:interaction)) diff --git a/common/src/app/common/types/shape/text.cljc b/common/src/app/common/types/shape/text.cljc index 25c2c8e072..464af2dfac 100644 --- a/common/src/app/common/types/shape/text.cljc +++ b/common/src/app/common/types/shape/text.cljc @@ -7,9 +7,7 @@ (ns app.common.types.shape.text (:require [app.common.schema :as sm] - [app.common.types.fills :refer [schema:fill]] - [app.common.types.shape :as-alias shape] - [app.common.types.shape.text.position-data :as-alias position-data])) + [app.common.types.fills :refer [schema:fill]])) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; SCHEMA @@ -63,26 +61,22 @@ [:typography-ref-id {:optional true} [:maybe ::sm/uuid]] [:typography-ref-file {:optional true} [:maybe ::sm/uuid]]]]]]]]]]]]]) -(sm/register! ::content schema:content) - (def valid-content? (sm/lazy-validator schema:content)) -(sm/register! - ^{::sm/type ::position-data} - [:vector {:min 1 :gen/max 2} - [:map - [:x ::sm/safe-number] - [:y ::sm/safe-number] - [:width ::sm/safe-number] - [:height ::sm/safe-number] - [:fills [:vector {:gen/max 2} schema:fill]] - [:font-family {:optional true} :string] - [:font-size {:optional true} :string] - [:font-style {:optional true} :string] - [:font-weight {:optional true} :string] - [:rtl {:optional true} :boolean] - [:text {:optional true} :string] - [:text-decoration {:optional true} :string] - [:text-transform {:optional true} :string]]]) - +(def schema:position-data + [:vector {:min 1 :gen/max 2} + [:map + [:x ::sm/safe-number] + [:y ::sm/safe-number] + [:width ::sm/safe-number] + [:height ::sm/safe-number] + [:fills [:vector {:gen/max 2} schema:fill]] + [:font-family {:optional true} :string] + [:font-size {:optional true} :string] + [:font-style {:optional true} :string] + [:font-weight {:optional true} :string] + [:rtl {:optional true} :boolean] + [:text {:optional true} :string] + [:text-decoration {:optional true} :string] + [:text-transform {:optional true} :string]]]) diff --git a/common/src/app/common/types/team.cljc b/common/src/app/common/types/team.cljc index f71c73f509..f8fe889c4f 100644 --- a/common/src/app/common/types/team.cljc +++ b/common/src/app/common/types/team.cljc @@ -17,4 +17,5 @@ :admin {:can-edit true :is-admin true :is-owner false} :owner {:can-edit true :is-admin true :is-owner true}}) -(sm/register! ::role [::sm/one-of valid-roles]) +(def schema:role + [::sm/one-of {:title "TeamRole"} valid-roles]) diff --git a/common/src/app/common/types/tokens_lib.cljc b/common/src/app/common/types/tokens_lib.cljc index 0f6601586e..7e098e5cab 100644 --- a/common/src/app/common/types/tokens_lib.cljc +++ b/common/src/app/common/types/tokens_lib.cljc @@ -1374,7 +1374,7 @@ Will return a value that matches this schema: (or tokens-lib (make-tokens-lib))) (def schema:tokens-lib - (sm/register! + (sm/type-schema {:type ::tokens-lib :pred valid-tokens-lib? :type-properties diff --git a/common/src/app/common/types/typography.cljc b/common/src/app/common/types/typography.cljc index 0f7052b994..b0c8a5bb89 100644 --- a/common/src/app/common/types/typography.cljc +++ b/common/src/app/common/types/typography.cljc @@ -18,26 +18,24 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (def schema:typography - (sm/register! - ^{::sm/type ::typography} - [:map {:title "Typography"} - [:id ::sm/uuid] - [:name :string] - [:font-id :string] - [:font-family :string] - [:font-variant-id :string] - [:font-size :string] - [:font-weight :string] - [:font-style :string] - [:line-height :string] - [:letter-spacing :string] - [:text-transform :string] - [:modified-at {:optional true} ::ct/inst] - [:path {:optional true} [:maybe :string]] - [:plugin-data {:optional true} ::ctpg/plugin-data]])) + [:map {:title "Typography"} + [:id ::sm/uuid] + [:name :string] + [:font-id :string] + [:font-family :string] + [:font-variant-id :string] + [:font-size :string] + [:font-weight :string] + [:font-style :string] + [:line-height :string] + [:letter-spacing :string] + [:text-transform :string] + [:modified-at {:optional true} ::ct/inst] + [:path {:optional true} [:maybe :string]] + [:plugin-data {:optional true} ctpg/schema:plugin-data]]) (def check-typography - (sm/check-fn ::typography)) + (sm/check-fn schema:typography)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; HELPERS diff --git a/common/src/app/common/types/variant.cljc b/common/src/app/common/types/variant.cljc index 9d5380a3dd..abad9f4b5f 100644 --- a/common/src/app/common/types/variant.cljc +++ b/common/src/app/common/types/variant.cljc @@ -22,34 +22,27 @@ [:value :string]]) (def schema:variant-component - ;; A component that is part of a variant set. - (sm/register! - ^{::sm/type ::variant-component} - [:map - [:variant-id {:optional true} ::sm/uuid] - [:variant-properties {:optional true} [:vector schema:variant-property]]])) + "A component that is part of a variant set" + [:map + [:variant-id {:optional true} ::sm/uuid] + [:variant-properties {:optional true} [:vector schema:variant-property]]]) (def schema:variant-shape - ;; The root shape of the main instance of a variant component. + "The root shape of the main instance of a variant component" [:map [:variant-id {:optional true} ::sm/uuid] [:variant-name {:optional true} :string] [:variant-error {:optional true} :string]]) (def schema:variant-container - ;; is a board that contains all variant components of a variant set, - ;; for grouping them visually in the workspace. + "Is a board that contains all variant components of a variant set, + for grouping them visually in the workspace" [:map [:is-variant-container {:optional true} :boolean]]) -(sm/register! ::variant-property schema:variant-property) -(sm/register! ::variant-shape schema:variant-shape) -(sm/register! ::variant-container schema:variant-container) - (def valid-variant-component? (sm/check-fn schema:variant-component)) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (def property-prefix "Property ") diff --git a/common/test/common_tests/types/shape_decode_encode_test.cljc b/common/test/common_tests/types/shape_decode_encode_test.cljc index 1c5d2be0e8..6b047c4fe2 100644 --- a/common/test/common_tests/types/shape_decode_encode_test.cljc +++ b/common/test/common_tests/types/shape_decode_encode_test.cljc @@ -14,7 +14,7 @@ [app.common.types.color :refer [schema:color schema:gradient]] [app.common.types.path :as path] [app.common.types.plugins :refer [schema:plugin-data]] - [app.common.types.shape :as tsh] + [app.common.types.shape :as tsh :refer [schema:shape]] [app.common.types.shape.interactions :refer [schema:animation schema:interaction]] [app.common.types.shape.shadow :refer [schema:shadow]] [app.common.uuid :as uuid] @@ -135,10 +135,10 @@ {:num 500}))) (t/deftest shape-json-roundtrip - (let [encode (sm/encoder ::tsh/shape (sm/json-transformer)) - decode (sm/decoder ::tsh/shape (sm/json-transformer))] + (let [encode (sm/encoder schema:shape (sm/json-transformer)) + decode (sm/decoder schema:shape (sm/json-transformer))] (smt/check! - (smt/for [shape (sg/generator ::tsh/shape)] + (smt/for [shape (sg/generator schema:shape)] (let [shape-1 (encode shape) shape-2 (json-roundtrip shape-1) shape-3 (decode shape-2)] diff --git a/frontend/src/app/main/data/changes.cljs b/frontend/src/app/main/data/changes.cljs index b2b41f7e5c..e8fc97862c 100644 --- a/frontend/src/app/main/data/changes.cljs +++ b/frontend/src/app/main/data/changes.cljs @@ -7,7 +7,6 @@ (ns app.main.data.changes (:require [app.common.data :as d] - [app.common.data.macros :as dm] [app.common.files.changes :as cpc] [app.common.logging :as log] [app.common.time :as ct] @@ -106,13 +105,11 @@ [{:keys [commit-id redo-changes undo-changes origin save-undo? features file-id file-revn file-vern undo-group tags stack-undo? source]}] - (dm/assert! - "expect valid vector of changes for redo-changes" - (cpc/check-changes! redo-changes)) + (assert (cpc/check-changes redo-changes) + "expect valid vector of changes for redo-changes") - (dm/assert! - "expect valid vector of changes for undo-changes" - (cpc/check-changes! undo-changes)) + (assert (cpc/check-changes undo-changes) + "expect valid vector of changes for undo-changes") (let [commit-id (or commit-id (uuid/next)) source (d/nilv source :local) diff --git a/frontend/src/app/main/data/workspace/libraries.cljs b/frontend/src/app/main/data/workspace/libraries.cljs index aeb9f3f3cc..0dc50ceb85 100644 --- a/frontend/src/app/main/data/workspace/libraries.cljs +++ b/frontend/src/app/main/data/workspace/libraries.cljs @@ -760,13 +760,11 @@ (defn ext-library-changed [library-id modified-at revn changes] - (dm/assert! - "expected valid uuid for library-id" - (uuid? library-id)) + (assert (uuid? library-id) + "expected valid uuid for library-id") - (dm/assert! - "expected valid changes vector" - (ch/check-changes! changes)) + (assert (ch/check-changes changes) + "expected valid changes vector") (ptk/reify ::ext-library-changed ptk/UpdateEvent diff --git a/frontend/src/app/main/data/workspace/notifications.cljs b/frontend/src/app/main/data/workspace/notifications.cljs index ba94f46604..4ecda05c32 100644 --- a/frontend/src/app/main/data/workspace/notifications.cljs +++ b/frontend/src/app/main/data/workspace/notifications.cljs @@ -236,7 +236,7 @@ [:session-id ::sm/uuid] [:revn :int] [:vern :int] - [:changes ::cpc/changes]]) + [:changes cpc/schema:changes]]) (def ^:private check-file-change-params! (sm/check-fn schema:handle-file-change)) @@ -279,9 +279,8 @@ (defn handle-file-restore [{:keys [file-id vern] :as msg}] - (dm/assert! - "expected valid parameters" - (check-file-restore-params msg)) + (assert (check-file-restore-params msg) + "expected valid parameters") (ptk/reify ::handle-file-restore ptk/WatchEvent @@ -302,16 +301,15 @@ [:session-id ::sm/uuid] [:revn :int] [:modified-at ::ct/inst] - [:changes ::cpc/changes]]) + [:changes cpc/schema:changes]]) -(def ^:private check-library-change-params! +(def ^:private check-library-change-params (sm/check-fn schema:handle-library-change)) (defn handle-library-change [{:keys [file-id modified-at changes revn] :as msg}] - (dm/assert! - "expected valid arguments" - (check-library-change-params! msg)) + (assert (check-library-change-params msg) + "expected valid arguments") (ptk/reify ::handle-library-change ptk/WatchEvent diff --git a/frontend/src/app/main/data/workspace/undo.cljs b/frontend/src/app/main/data/workspace/undo.cljs index 724ae94309..fe9f26bcad 100644 --- a/frontend/src/app/main/data/workspace/undo.cljs +++ b/frontend/src/app/main/data/workspace/undo.cljs @@ -57,8 +57,8 @@ (def ^:private schema:undo-entry [:map {:title "undo-entry"} - [:undo-changes [:vector ::cpc/change]] - [:redo-changes [:vector ::cpc/change]] + [:undo-changes [:vector cpc/schema:change]] + [:redo-changes [:vector cpc/schema:change]] [:undo-group ::sm/uuid] [:tags [:set :keyword]]]) diff --git a/frontend/src/app/plugins/shape.cljs b/frontend/src/app/plugins/shape.cljs index 55fe987d8e..a12ce086b9 100644 --- a/frontend/src/app/plugins/shape.cljs +++ b/frontend/src/app/plugins/shape.cljs @@ -119,7 +119,7 @@ (-> (u/proxy->interaction self) (d/patch-object params))] (cond - (not (sm/validate ::ctsi/interaction interaction)) + (not (sm/validate ctsi/schema:interaction interaction)) (u/display-not-valid :action interaction) :else @@ -453,7 +453,7 @@ (let [id (obj/get self "$id") value (blur-defaults (parser/parse-blur value))] (cond - (not (sm/validate ::ctsb/blur value)) + (not (sm/validate ctsb/schema:blur value)) (u/display-not-valid :blur value) (not (r/check-permission plugin-id "content:write")) @@ -470,7 +470,7 @@ (let [id (obj/get self "$id") value (parser/parse-exports value)] (cond - (not (sm/validate [:vector ::ctse/export] value)) + (not (sm/validate [:vector ctse/schema:export] value)) (u/display-not-valid :exports value) (not (r/check-permission plugin-id "content:write")) @@ -1129,7 +1129,7 @@ (fn [value] (let [value (parser/parse-export value)] (cond - (not (sm/validate ::ctse/export value)) + (not (sm/validate ctse/schema:export value)) (u/display-not-valid :export value) :else @@ -1161,7 +1161,7 @@ (-> ctsi/default-interaction (d/patch-object (parser/parse-interaction trigger action delay)))] (cond - (not (sm/validate ::ctsi/interaction interaction)) + (not (sm/validate ctsi/schema:interaction interaction)) (u/display-not-valid :addInteraction interaction) :else diff --git a/library/src/lib/export.cljs b/library/src/lib/export.cljs index 1d5d5cfcb6..72c779c24e 100644 --- a/library/src/lib/export.cljs +++ b/library/src/lib/export.cljs @@ -54,7 +54,7 @@ (sm/encoder types.tokens-lib/schema:tokens-lib sm/json-transformer)) (def encode-plugin-data - (sm/encoder ::ctpg/plugin-data sm/json-transformer)) + (sm/encoder ctpg/schema:plugin-data sm/json-transformer)) (def ^:private valid-buckets #{"file-media-object"