mirror of
https://github.com/penpot/penpot.git
synced 2025-02-12 18:18:24 -05:00
🎉 Add common
directory tree for code sharing between front and back.
This commit is contained in:
parent
ca3a42f680
commit
5b96e1e9fd
14 changed files with 288 additions and 41 deletions
|
@ -44,7 +44,7 @@
|
|||
|
||||
mount/mount {:mvn/version "0.1.16"}
|
||||
environ/environ {:mvn/version "1.1.0"}}
|
||||
:paths ["src" "vendor" "resources"]
|
||||
:paths ["src" "vendor" "resources" "../common"]
|
||||
:aliases
|
||||
{:dev
|
||||
{:extra-deps
|
||||
|
|
|
@ -43,8 +43,8 @@
|
|||
width 200
|
||||
height 200}
|
||||
:as opts}]
|
||||
{:pre [(us/valid? ::thumbnail-opts opts)
|
||||
(fs/path? input)]}
|
||||
(s/assert ::thumbnail-opts opts)
|
||||
(s/assert fs/path? input)
|
||||
(let [tmp (fs/create-tempfile :suffix (str "." format))
|
||||
opr (doto (IMOperation.)
|
||||
(.addImage)
|
||||
|
@ -60,9 +60,7 @@
|
|||
|
||||
(defn make-thumbnail
|
||||
[input {:keys [width height format quality] :as opts}]
|
||||
{:pre [(us/valid? ::thumbnail-opts opts)
|
||||
(or (string? input)
|
||||
(fs/path input))]}
|
||||
(s/assert ::thumbnail-opts opts)
|
||||
(let [[filename ext] (fs/split-ext (fs/name input))
|
||||
suffix (->> [width height quality format]
|
||||
(interpose ".")
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
(s/def ::name ::us/string)
|
||||
(s/def ::path ::us/string)
|
||||
(s/def ::regex us/regex?)
|
||||
(s/def ::regex #(instance? java.util.regex.Pattern %))
|
||||
(s/def ::import-item
|
||||
(s/keys :req-un [::name ::path ::regex]))
|
||||
|
||||
|
|
|
@ -13,22 +13,22 @@
|
|||
[uxbox.services.mutations.project-files :as files]
|
||||
[uxbox.services.queries.project-pages :refer [decode-row]]
|
||||
[uxbox.services.util :as su]
|
||||
[uxbox.common.pages :as cp]
|
||||
[uxbox.common.spec :as cs]
|
||||
[uxbox.util.exceptions :as ex]
|
||||
[uxbox.util.blob :as blob]
|
||||
[uxbox.util.spec :as us]
|
||||
[uxbox.util.sql :as sql]
|
||||
[uxbox.util.uuid :as uuid]))
|
||||
|
||||
;; --- Helpers & Specs
|
||||
|
||||
;; TODO: validate `:data` and `:metadata`
|
||||
|
||||
(s/def ::id ::us/uuid)
|
||||
(s/def ::name ::us/string)
|
||||
(s/def ::data any?)
|
||||
(s/def ::user ::us/uuid)
|
||||
(s/def ::project-id ::us/uuid)
|
||||
(s/def ::metadata any?)
|
||||
(s/def ::ordering ::us/number)
|
||||
(s/def ::id ::cs/uuid)
|
||||
(s/def ::name ::cs/string)
|
||||
(s/def ::data ::cp/data)
|
||||
(s/def ::user ::cs/uuid)
|
||||
(s/def ::project-id ::cs/uuid)
|
||||
(s/def ::metadata ::cp/metadata)
|
||||
(s/def ::ordering ::cs/number)
|
||||
|
||||
;; --- Mutation: Create Page
|
||||
|
||||
|
|
|
@ -26,9 +26,6 @@
|
|||
Buffer
|
||||
(->bytes [data] (.getBytes ^Buffer data))
|
||||
|
||||
;; org.jooq.JSONB
|
||||
;; (->bytes [data] (->bytes (.toString data)))
|
||||
|
||||
String
|
||||
(->bytes [data] (.getBytes ^String data "UTF-8")))
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
(:require [clojure.walk :as walk]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
;; TODO: move to uxbox.common.helpers
|
||||
|
||||
(defn dissoc-in
|
||||
[m [k & ks :as keys]]
|
||||
(if ks
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
"A helpers for work with exceptions."
|
||||
(:require [clojure.spec.alpha :as s]))
|
||||
|
||||
;; TODO: moved to uxbox.common.exceptions
|
||||
|
||||
(s/def ::type keyword?)
|
||||
(s/def ::code keyword?)
|
||||
(s/def ::mesage string?)
|
||||
|
|
|
@ -65,10 +65,6 @@
|
|||
(with-open [input (ByteArrayInputStream. data)]
|
||||
(read! (reader input opts)))
|
||||
|
||||
;; ;; TODO: temporal
|
||||
;; (instance? org.jooq.JSONB data)
|
||||
;; (decode (.toString data) opts)
|
||||
|
||||
(string? data)
|
||||
(decode (.getBytes data "UTF-8") opts)
|
||||
|
||||
|
|
|
@ -12,19 +12,17 @@
|
|||
[clojure.pprint :refer [pprint]]
|
||||
[clojure.test :as test]
|
||||
[clojure.java.io :as io]
|
||||
[clojure.repl :refer :all]
|
||||
[criterium.core :refer [quick-bench bench with-progress-reporting]]
|
||||
[expound.alpha :as expound]
|
||||
[promesa.core :as p]
|
||||
[sieppari.core :as sp]
|
||||
[sieppari.context :as spx]
|
||||
[buddy.core.codecs :as codecs]
|
||||
[buddy.core.codecs.base64 :as b64]
|
||||
[buddy.core.nonce :as nonce]
|
||||
;; [sieppari.core :as sp]
|
||||
;; [sieppari.context :as spx]
|
||||
;; [buddy.core.codecs :as codecs]
|
||||
;; [buddy.core.codecs.base64 :as b64]
|
||||
;; [buddy.core.nonce :as nonce]
|
||||
[mount.core :as mount]
|
||||
[uxbox.main]
|
||||
[uxbox.util.sql :as sql]
|
||||
[uxbox.util.blob :as blob])
|
||||
(:gen-class))
|
||||
[uxbox.main]))
|
||||
|
||||
(defmacro run-quick-bench
|
||||
[& exprs]
|
||||
|
@ -51,11 +49,11 @@
|
|||
|
||||
;; --- Development Stuff
|
||||
|
||||
(defn- make-secret
|
||||
[]
|
||||
(-> (nonce/random-bytes 64)
|
||||
(b64/encode true)
|
||||
(codecs/bytes->str)))
|
||||
;; (defn- make-secret
|
||||
;; []
|
||||
;; (-> (nonce/random-bytes 64)
|
||||
;; (b64/encode true)
|
||||
;; (codecs/bytes->str)))
|
||||
|
||||
(defn- start
|
||||
[]
|
||||
|
|
32
common/uxbox/common/exceptions.cljc
Normal file
32
common/uxbox/common/exceptions.cljc
Normal file
|
@ -0,0 +1,32 @@
|
|||
;; 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) 2016-2019 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.util.exceptions
|
||||
"A helpers for work with exceptions."
|
||||
(:require [clojure.spec.alpha :as s]))
|
||||
|
||||
(s/def ::type keyword?)
|
||||
(s/def ::code keyword?)
|
||||
(s/def ::mesage string?)
|
||||
(s/def ::hint string?)
|
||||
|
||||
(s/def ::error
|
||||
(s/keys :req-un [::type]
|
||||
:opt-un [::code
|
||||
::hint
|
||||
::mesage]))
|
||||
|
||||
(defn error
|
||||
[& {:keys [type code message hint cause] :as params}]
|
||||
(s/assert ::error params)
|
||||
(let [message (or message hint "")
|
||||
payload (dissoc params :cause :message)]
|
||||
(ex-info message payload cause)))
|
||||
|
||||
#?(:clj
|
||||
(defmacro raise
|
||||
[& args]
|
||||
`(throw (error ~@args))))
|
96
common/uxbox/common/pages.cljc
Normal file
96
common/uxbox/common/pages.cljc
Normal file
|
@ -0,0 +1,96 @@
|
|||
(ns uxbox.common.pages
|
||||
"A common (clj/cljs) functions and specs for pages."
|
||||
(:require
|
||||
[clojure.spec.alpha :as s]
|
||||
[uxbox.common.spec :as cs]))
|
||||
|
||||
;; --- Specs
|
||||
|
||||
(s/def ::id ::cs/uuid)
|
||||
(s/def ::name string?)
|
||||
(s/def ::type keyword?)
|
||||
|
||||
;; Metadata related
|
||||
(s/def ::grid-x-axis ::cs/number)
|
||||
(s/def ::grid-y-axis ::cs/number)
|
||||
(s/def ::grid-color string?)
|
||||
(s/def ::background string?)
|
||||
(s/def ::background-opacity ::cs/number)
|
||||
|
||||
;; Page related
|
||||
(s/def ::file-id ::cs/uuid)
|
||||
(s/def ::user ::cs/uuid)
|
||||
(s/def ::created-at ::cs/inst)
|
||||
(s/def ::modified-at ::cs/inst)
|
||||
(s/def ::version ::cs/number)
|
||||
(s/def ::ordering ::cs/number)
|
||||
|
||||
;; Page Data related
|
||||
(s/def ::shape
|
||||
(s/keys :req-un [::type ::name]
|
||||
:opt-un [::id]))
|
||||
|
||||
(s/def ::shapes (s/coll-of ::cs/uuid :kind vector?))
|
||||
(s/def ::canvas (s/coll-of ::cs/uuid :kind vector?))
|
||||
|
||||
(s/def ::shapes-by-id
|
||||
(s/map-of uuid? ::shape))
|
||||
|
||||
;; Main
|
||||
|
||||
(s/def ::data
|
||||
(s/keys :req-un [::shapes ::canvas ::shapes-by-id]))
|
||||
|
||||
|
||||
(s/def ::metadata
|
||||
(s/keys :opt-un [::grid-y-axis
|
||||
::grid-x-axis
|
||||
::grid-color
|
||||
::background
|
||||
::background-opacity]))
|
||||
|
||||
(s/def ::opeation
|
||||
(s/or :mod-shape (s/cat :name #(= % :mod-shape)
|
||||
:id uuid?
|
||||
:attr keyword?
|
||||
:value any?)
|
||||
:add-shape (s/cat :name #(= % :add-shape)
|
||||
:id uuid?
|
||||
:data any?)
|
||||
:del-shape (s/cat :name #(= % :del-shape)
|
||||
:id uuid?)))
|
||||
|
||||
;; --- Operations Processing Impl
|
||||
|
||||
(declare process-operation)
|
||||
(declare process-add-shape)
|
||||
(declare process-mod-shape)
|
||||
(declare process-del-shape)
|
||||
|
||||
(defn process-ops
|
||||
[data operations]
|
||||
(reduce process-operation data operations))
|
||||
|
||||
(defn- process-operation
|
||||
[data operation]
|
||||
(case (first operation)
|
||||
:add-shape (process-add-shape data operation)
|
||||
:mod-shape (process-mod-shape data operation)
|
||||
:del-shape (process-del-shape data operation)))
|
||||
|
||||
(defn- process-add-shape
|
||||
[data {:keys [id data]}]
|
||||
(-> data
|
||||
(update :shapes conj id)
|
||||
(update :shapes-by-id assoc id data)))
|
||||
|
||||
(defn- process-mod-shape
|
||||
[data {:keys [id attr value]}]
|
||||
(update-in data [:shapes-by-id id] assoc attr value))
|
||||
|
||||
(defn- process-del-shape
|
||||
[data {:keys [id attr value]}]
|
||||
(-> data
|
||||
(update :shapes (fn [s] (filterv #(not= % id) s)))
|
||||
(update :shapes-by-id dissoc id)))
|
||||
|
120
common/uxbox/common/spec.cljc
Normal file
120
common/uxbox/common/spec.cljc
Normal file
|
@ -0,0 +1,120 @@
|
|||
;; 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) 2016-2019 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.common.spec
|
||||
(:require
|
||||
[clojure.spec.alpha :as s]
|
||||
[cuerdas.core :as str]
|
||||
#?(:clj [datoteka.core :as fs])))
|
||||
|
||||
(s/check-asserts true)
|
||||
|
||||
;; --- Constants
|
||||
|
||||
(def email-rx
|
||||
#"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$")
|
||||
|
||||
(def uuid-rx
|
||||
#"^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$")
|
||||
|
||||
(def number-rx
|
||||
#"^[+-]?([0-9]*\.?[0-9]+|[0-9]+\.?[0-9]*)([eE][+-]?[0-9]+)?$")
|
||||
|
||||
;; --- Predicates
|
||||
|
||||
(defn email?
|
||||
[v]
|
||||
(and (string? v)
|
||||
(re-matches email-rx v)))
|
||||
|
||||
;; --- Conformers
|
||||
|
||||
(defn- uuid-conformer
|
||||
[v]
|
||||
(cond
|
||||
(uuid? v) v
|
||||
(string? v)
|
||||
(cond
|
||||
(re-matches uuid-rx v)
|
||||
#?(:clj (java.util.UUID/fromString v)
|
||||
:cljs (uuid v))
|
||||
|
||||
(str/empty? v)
|
||||
nil
|
||||
|
||||
:else
|
||||
::s/invalid)
|
||||
:else ::s/invalid))
|
||||
|
||||
(defn- integer-conformer
|
||||
[v]
|
||||
(cond
|
||||
(integer? v) v
|
||||
(string? v)
|
||||
(if (re-matches #"^[-+]?\d+$" v)
|
||||
(Long/parseLong v)
|
||||
::s/invalid)
|
||||
:else ::s/invalid))
|
||||
|
||||
(defn boolean-conformer
|
||||
[v]
|
||||
(cond
|
||||
(boolean? v) v
|
||||
(string? v)
|
||||
(if (re-matches #"^(?:t|true|false|f|0|1)$" v)
|
||||
(contains? #{"t" "true" "1"} v)
|
||||
::s/invalid)
|
||||
:else ::s/invalid))
|
||||
|
||||
(defn boolean-unformer
|
||||
[v]
|
||||
(if v "true" "false"))
|
||||
|
||||
#?(:clj
|
||||
(defn path-conformer
|
||||
[v]
|
||||
(cond
|
||||
(string? v) (fs/path v)
|
||||
(fs/path? v) v
|
||||
:else ::s/invalid)))
|
||||
|
||||
(defn- number-conformer
|
||||
[v]
|
||||
(cond
|
||||
(number? v) v
|
||||
|
||||
(str/numeric? v)
|
||||
#?(:clj (Double/parseDouble v)
|
||||
:cljs (js/parseFloat v))
|
||||
|
||||
:else ::s/invalid))
|
||||
|
||||
;; --- Default Specs
|
||||
|
||||
(s/def ::string string?)
|
||||
(s/def ::integer (s/conformer integer-conformer str))
|
||||
(s/def ::uuid (s/conformer uuid-conformer str))
|
||||
(s/def ::boolean (s/conformer boolean-conformer boolean-unformer))
|
||||
(s/def ::number (s/conformer number-conformer str))
|
||||
|
||||
(s/def ::inst inst?)
|
||||
(s/def ::positive pos?)
|
||||
(s/def ::negative neg?)
|
||||
(s/def ::uploaded-file any?)
|
||||
(s/def ::email email?)
|
||||
(s/def ::file any?)
|
||||
|
||||
;; Clojure Specific
|
||||
#?(:clj
|
||||
(do
|
||||
(s/def ::bytes bytes?)
|
||||
(s/def ::name ::string)
|
||||
(s/def ::size ::integer)
|
||||
(s/def ::mtype ::string)
|
||||
(s/def ::path (s/conformer path-conformer str))
|
||||
(s/def ::upload
|
||||
(s/keys :req-un [::name ::path ::size ::mtype]))))
|
||||
|
|
@ -30,12 +30,14 @@
|
|||
(s/def ::version ::us/number)
|
||||
(s/def ::width (s/and ::us/number ::us/positive))
|
||||
(s/def ::height (s/and ::us/number ::us/positive))
|
||||
|
||||
(s/def ::grid-x-axis ::us/number)
|
||||
(s/def ::grid-y-axis ::us/number)
|
||||
(s/def ::grid-color ::us/string)
|
||||
(s/def ::ordering ::us/number)
|
||||
(s/def ::background ::us/string)
|
||||
(s/def ::background-opacity ::us/number)
|
||||
|
||||
(s/def ::ordering ::us/number)
|
||||
(s/def ::user ::us/uuid)
|
||||
|
||||
(s/def ::metadata
|
||||
|
@ -45,12 +47,14 @@
|
|||
::background
|
||||
::background-opacity]))
|
||||
|
||||
;; TODO: start using uxbox.common.pagedata/data spec ...
|
||||
|
||||
(s/def ::minimal-shape
|
||||
(s/keys :req-un [::type ::name]
|
||||
:opt-un [::id]))
|
||||
|
||||
(s/def ::shapes (s/every ::us/uuid :kind vector? :into []))
|
||||
(s/def ::canvas (s/every ::us/uuid :kind vector? :into []))
|
||||
(s/def ::shapes (s/coll-of ::us/uuid :kind vector?))
|
||||
(s/def ::canvas (s/coll-of ::us/uuid :kind vector?))
|
||||
|
||||
(s/def ::shapes-by-id
|
||||
(s/map-of ::us/uuid ::minimal-shape))
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
(:require [cljs.reader :as r]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
;; TODO: partially move to uxbox.common.helpers
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Data structure manipulation
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
|
Loading…
Add table
Reference in a new issue