mirror of
https://github.com/penpot/penpot.git
synced 2025-05-24 00:26:11 +02:00
✨ Add minor improvements to common.schema ns
This commit is contained in:
parent
7be79c10fd
commit
0fa8aca6e2
2 changed files with 97 additions and 19 deletions
|
@ -21,6 +21,7 @@
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[malli.core :as m]
|
[malli.core :as m]
|
||||||
[malli.dev.pretty :as mdp]
|
[malli.dev.pretty :as mdp]
|
||||||
|
[malli.dev.virhe :as v]
|
||||||
[malli.error :as me]
|
[malli.error :as me]
|
||||||
[malli.generator :as mg]
|
[malli.generator :as mg]
|
||||||
[malli.registry :as mr]
|
[malli.registry :as mr]
|
||||||
|
@ -104,6 +105,10 @@
|
||||||
[exp]
|
[exp]
|
||||||
(malli.error/error-value exp {:malli.error/mask-valid-values '...}))
|
(malli.error/error-value exp {:malli.error/mask-valid-values '...}))
|
||||||
|
|
||||||
|
(defn optional-keys
|
||||||
|
[schema]
|
||||||
|
(mu/optional-keys schema default-options))
|
||||||
|
|
||||||
(def default-transformer
|
(def default-transformer
|
||||||
(let [default-decoder
|
(let [default-decoder
|
||||||
{:compile (fn [s _registry]
|
{:compile (fn [s _registry]
|
||||||
|
@ -190,9 +195,10 @@
|
||||||
(fn [v] (@vfn v))))
|
(fn [v] (@vfn v))))
|
||||||
|
|
||||||
(defn lazy-decoder
|
(defn lazy-decoder
|
||||||
[s transformer]
|
([s] (lazy-decoder s default-transformer))
|
||||||
|
([s transformer]
|
||||||
(let [vfn (delay (decoder (if (delay? s) (deref s) s) transformer))]
|
(let [vfn (delay (decoder (if (delay? s) (deref s) s) transformer))]
|
||||||
(fn [v] (@vfn v))))
|
(fn [v] (@vfn v)))))
|
||||||
|
|
||||||
(defn humanize-explain
|
(defn humanize-explain
|
||||||
[{:keys [schema errors value]} & {:keys [length level]}]
|
[{:keys [schema errors value]} & {:keys [length level]}]
|
||||||
|
@ -207,9 +213,29 @@
|
||||||
:level (d/nilv level 8)
|
:level (d/nilv level 8)
|
||||||
:length (d/nilv length 12)})))))
|
:length (d/nilv length 12)})))))
|
||||||
|
|
||||||
|
|
||||||
|
(defmethod v/-format ::schemaless-explain
|
||||||
|
[_ {:keys [schema] :as explanation} printer]
|
||||||
|
{:body [:group
|
||||||
|
(v/-block "Value" (v/-visit (me/error-value explanation printer) printer) printer) :break :break
|
||||||
|
(v/-block "Errors" (v/-visit (me/humanize (me/with-spell-checking explanation)) printer) printer) :break :break
|
||||||
|
(v/-block "Schema" (v/-visit schema printer) printer)]})
|
||||||
|
|
||||||
|
|
||||||
|
(defmethod v/-format ::explain
|
||||||
|
[_ {:keys [schema] :as explanation} printer]
|
||||||
|
{:body [:group
|
||||||
|
(v/-block "Value" (v/-visit (me/error-value explanation printer) printer) printer) :break :break
|
||||||
|
(v/-block "Errors" (v/-visit (me/humanize (me/with-spell-checking explanation)) printer) printer) :break :break
|
||||||
|
(v/-block "Schema" (v/-visit schema printer) printer)]})
|
||||||
|
|
||||||
|
|
||||||
(defn pretty-explain
|
(defn pretty-explain
|
||||||
[s d]
|
[explain & {:keys [variant message]
|
||||||
(mdp/explain (schema s) d))
|
:or {variant ::explain
|
||||||
|
message "Validation Error"}}]
|
||||||
|
(let [explain (fn [] (me/with-error-messages explain))]
|
||||||
|
((mdp/prettifier variant message explain default-options))))
|
||||||
|
|
||||||
(defmacro ignoring
|
(defmacro ignoring
|
||||||
[expr]
|
[expr]
|
||||||
|
@ -297,7 +323,7 @@
|
||||||
(throw (ex-info hint options))))))
|
(throw (ex-info hint options))))))
|
||||||
|
|
||||||
(defn validate-fn
|
(defn validate-fn
|
||||||
"Create a predefined validate function"
|
"Create a predefined validate function that raises an expception"
|
||||||
[s]
|
[s]
|
||||||
(let [schema (if (lazy-schema? s) s (define s))]
|
(let [schema (if (lazy-schema? s) s (define s))]
|
||||||
(partial fast-validate! schema)))
|
(partial fast-validate! schema)))
|
||||||
|
@ -317,6 +343,7 @@
|
||||||
hint (get options :hint "schema validation error")]
|
hint (get options :hint "schema validation error")]
|
||||||
(throw (ex-info hint options)))))))
|
(throw (ex-info hint options)))))))
|
||||||
|
|
||||||
|
;; FIXME: revisit
|
||||||
(defn conform!
|
(defn conform!
|
||||||
[schema value]
|
[schema value]
|
||||||
(assert (lazy-schema? schema) "expected `schema` to satisfy ILazySchema protocol")
|
(assert (lazy-schema? schema) "expected `schema` to satisfy ILazySchema protocol")
|
||||||
|
@ -476,11 +503,14 @@
|
||||||
|
|
||||||
(define! ::set
|
(define! ::set
|
||||||
{:type :set
|
{:type :set
|
||||||
|
:min 0
|
||||||
|
:max 1
|
||||||
:compile
|
:compile
|
||||||
(fn [{:keys [coerce kind max min] :as props} _ _]
|
(fn [{:keys [coerce kind max min] :as props} children _]
|
||||||
(let [xform (if coerce
|
(let [xform (if coerce
|
||||||
(comp non-empty-strings-xf (map coerce))
|
(comp non-empty-strings-xf (map coerce))
|
||||||
non-empty-strings-xf)
|
non-empty-strings-xf)
|
||||||
|
kind (or (last children) kind)
|
||||||
pred (cond
|
pred (cond
|
||||||
(fn? kind) kind
|
(fn? kind) kind
|
||||||
(nil? kind) any?
|
(nil? kind) any?
|
||||||
|
@ -509,7 +539,8 @@
|
||||||
(every? pred value))))
|
(every? pred value))))
|
||||||
|
|
||||||
:else
|
:else
|
||||||
pred)]
|
(fn [value]
|
||||||
|
(every? pred value)))]
|
||||||
|
|
||||||
{:pred pred
|
{:pred pred
|
||||||
:type-properties
|
:type-properties
|
||||||
|
@ -525,6 +556,64 @@
|
||||||
(let [v (if (string? v) (str/split v #"[\s,]+") v)]
|
(let [v (if (string? v) (str/split v #"[\s,]+") v)]
|
||||||
(into #{} xform v)))}}))})
|
(into #{} xform v)))}}))})
|
||||||
|
|
||||||
|
|
||||||
|
(define! ::vec
|
||||||
|
{:type :vector
|
||||||
|
:min 0
|
||||||
|
:max 1
|
||||||
|
:compile
|
||||||
|
(fn [{:keys [coerce kind max min] :as props} children _]
|
||||||
|
(let [xform (if coerce
|
||||||
|
(comp non-empty-strings-xf (map coerce))
|
||||||
|
non-empty-strings-xf)
|
||||||
|
|
||||||
|
kind (or (last children) kind)
|
||||||
|
pred (cond
|
||||||
|
(fn? kind) kind
|
||||||
|
(nil? kind) any?
|
||||||
|
:else (validator kind))
|
||||||
|
|
||||||
|
pred (cond
|
||||||
|
(and max min)
|
||||||
|
(fn [value]
|
||||||
|
(let [size (count value)]
|
||||||
|
(and (set? value)
|
||||||
|
(<= min size max)
|
||||||
|
(every? pred value))))
|
||||||
|
|
||||||
|
min
|
||||||
|
(fn [value]
|
||||||
|
(let [size (count value)]
|
||||||
|
(and (set? value)
|
||||||
|
(<= min size)
|
||||||
|
(every? pred value))))
|
||||||
|
|
||||||
|
max
|
||||||
|
(fn [value]
|
||||||
|
(let [size (count value)]
|
||||||
|
(and (set? value)
|
||||||
|
(<= size max)
|
||||||
|
(every? pred value))))
|
||||||
|
|
||||||
|
:else
|
||||||
|
(fn [value]
|
||||||
|
(every? pred value)))]
|
||||||
|
|
||||||
|
{:pred pred
|
||||||
|
:type-properties
|
||||||
|
{:title "set"
|
||||||
|
:description "Set of Strings"
|
||||||
|
:error/message "should be a set of strings"
|
||||||
|
:gen/gen (-> kind sg/generator sg/set)
|
||||||
|
::oapi/type "array"
|
||||||
|
::oapi/format "set"
|
||||||
|
::oapi/items {:type "string"}
|
||||||
|
::oapi/unique-items true
|
||||||
|
::oapi/decode (fn [v]
|
||||||
|
(let [v (if (string? v) (str/split v #"[\s,]+") v)]
|
||||||
|
(into [] xform v)))}}))})
|
||||||
|
|
||||||
|
|
||||||
(define! ::set-of-strings
|
(define! ::set-of-strings
|
||||||
{:type ::set-of-strings
|
{:type ::set-of-strings
|
||||||
:pred #(and (set? %) (every? string? %))
|
:pred #(and (set? %) (every? string? %))
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.logging :as log]
|
[app.common.logging :as log]
|
||||||
[app.common.schema :as sm]
|
[app.common.schema :as sm]
|
||||||
[app.common.spec :as us]
|
|
||||||
[app.config :as cf]
|
[app.config :as cf]
|
||||||
[app.main.data.messages :as msg]
|
[app.main.data.messages :as msg]
|
||||||
[app.main.data.users :as du]
|
[app.main.data.users :as du]
|
||||||
|
@ -25,7 +24,6 @@
|
||||||
[app.util.keyboard :as k]
|
[app.util.keyboard :as k]
|
||||||
[app.util.router :as rt]
|
[app.util.router :as rt]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[cljs.spec.alpha :as s]
|
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(def show-alt-login-buttons?
|
(def show-alt-login-buttons?
|
||||||
|
@ -64,14 +62,6 @@
|
||||||
:else
|
:else
|
||||||
(st/emit! (msg/error (tr "errors.generic"))))))))
|
(st/emit! (msg/error (tr "errors.generic"))))))))
|
||||||
|
|
||||||
(s/def ::email ::us/email)
|
|
||||||
(s/def ::password ::us/not-empty-string)
|
|
||||||
(s/def ::invitation-token ::us/not-empty-string)
|
|
||||||
|
|
||||||
(s/def ::login-form
|
|
||||||
(s/keys :req-un [::email ::password]
|
|
||||||
:opt-un [::invitation-token]))
|
|
||||||
|
|
||||||
(def ^:private schema:login-form
|
(def ^:private schema:login-form
|
||||||
[:map {:title "LoginForm"}
|
[:map {:title "LoginForm"}
|
||||||
[:email [::sm/email {:error/code "errors.invalid-email"}]]
|
[:email [::sm/email {:error/code "errors.invalid-email"}]]
|
||||||
|
@ -84,7 +74,6 @@
|
||||||
(let [initial (mf/with-memo [params] params)
|
(let [initial (mf/with-memo [params] params)
|
||||||
error (mf/use-state false)
|
error (mf/use-state false)
|
||||||
form (fm/use-form :schema schema:login-form
|
form (fm/use-form :schema schema:login-form
|
||||||
;; :validators [handle-error-messages]
|
|
||||||
:initial initial)
|
:initial initial)
|
||||||
|
|
||||||
on-error
|
on-error
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue