Fork me on GitHub

@pedroabelleira need to clean it up first, hopefully before summer vacations

ūüĎć 3

a proposed fix to look up errors from parent schemas, finally:


fixes #86:

(-> [:map
     [:foo {:error/message "entry-failure"} :int]]
    (m/explain {:foo "1"})
    (me/humanize {:resolve me/resolve-root-error-message-and-path}))
; => {:foo ["entry-failure"]}


the new hook in humanize allows custom collector, here, it just traverses the parents to look for error definitons, which will override the more exact definitions.


we could have a m/humanizer that would prepare the humanization and would be much faster, e.g.

(def Schema
   [:foo {:error/message "foo!"} :int]
   [:bar {:error/message "bar!"} :int]])

(def humanize (me/humanizer Schema)

(-> Schema 
    (m/explain {:foo "1", :bar "1"}) 
; => {:foo ["foo!"], :bar ["bar!]}

Grigory Shepelev07:06:43

Hello there. Need a little help. How do I malli/get-in with spec with registry? Suppose having the following structure

(def registry
      [:id int?
       :is_bot boolean?]]]]
    [:from {:optional true} [:ref "users"]]
    [:id int?]
    [:text {:optional true} string?]
    [:reply {:optional true} [:ref "messages"]]]})
And I've tried a lot of different combinations like:
(let [s (malli/schema [:schema {:registry registry} "messages"])
                        _ (print (malli/schema? s))] 
                    (u/get-in s [:id]))
true;; => nil
No success.

Ben Sless08:06:23

You have three mistakes: ‚ÄĘ syntax error in registry definition (look at the telegram map) ‚ÄĘ the registry you pass to the schema constructor is incomplete, you need to merge it with the default registry ‚ÄĘ The path you get-in is wrong, schema-schemas are considered part of the path and their children are at key 0.


should malli default to allowing the default registry o be swapped? e.g. strict mode where it can’t (for those who want to be fully in control).

Ben Sless14:06:11

I think it would be better to merge the provided registry with the default registry be default. I always forget that


one option should be not to have defauts schemas, only way to get proper DCE for tiny lib size, e.g. busy frontends.


currently the smallest usefull malli-bundle is 2.3kb (gzipped js)


with default registry, it’t 37kb.

Ben Sless17:06:59

How is that measured? I never worked with cljs. Does the compiler eliminate dead code?


there is a guide how to do that (with shadow-cljs) in malli readme. In short: ‚ÄĘ unsed functions and protocol methods (and definitions) will be DCEd ‚ÄĘ multimethods and deffed values are not


this is the reason all malli registry parts are behind a function -> no-one calling it => get’s eliminated under advanced.

ūüôĆ 3

seems that all the malli-codebases I have worked with, have introduced a custom mutable registry…


you can always do evil:

(reset! @#'mr/registry* (mr/mutable-registry registry*))


Hi! I want to create a schema for a sequence like this

[{:type  :type1
  :attrs {:type1-prop 1}}
 {:type  :type2
  :attrs {:type2-prop 2}}]
:attrs schema will be different for different object types. There’s :multi, but the dispatch property :type is on the parent of the object inside :attrs. Is the problem description clear, and does anyone have a good/best practice for solving this with malli?


@ingesol maybe:

(require '[malli.generator :as mg])

  [:multi {:dispatch :type}
   [:type1 [:map
            [:type [:= :type1]]
            [:attrs [:map
                     [:type1-prop :int]]]]]
   [:type2 [:map
            [:type [:= :type2]]
            [:attrs [:map
                     [:type2-prop :int]]]]]])
;({:type :type1, :attrs {:type1-prop -1}}
; {:type :type2, :attrs {:type2-prop -1}}
; {:type :type1, :attrs {:type1-prop -1}}
; {:type :type1, :attrs {:type1-prop -1}}
; {:type :type1, :attrs {:type1-prop -2}}
; {:type :type1, :attrs {:type1-prop 0}}
; {:type :type2, :attrs {:type2-prop 12}}
; {:type :type2, :attrs {:type2-prop 4}}
; {:type :type2, :attrs {:type2-prop -26}}
; {:type :type1, :attrs {:type1-prop -14}})


@ikitommi Thanks! Yes, I thought about something like that too. My maps are bigger than in this minimal example, but easy enough to create the schemas with a factory function i guess.

ūüĎć 3

Newbie here... I am trying to run the base code example from the lambdaisland/regal example page My Deps.edn looks like {:deps {org.clojure/clojure {:mvn/version "1.10.3"}         `org.clojure/core.async {:mvn/version "1.3.618"}`         `org.clojure/test.check {:mvn/version "1.1.0"}`         `lambdaisland/regal {:mvn/version "0.0.97"}`         `metosin/reitit-malli {:mvn/version "0.4.2"}}` and my clojure code is as follows (ns baseClj.core   `(:require [malli.core :as m]`             `[malli.error :as me]`             `[malli.generator :as mg]`             `[lambdaisland.regal.malli :as regal-malli]`             `;; [lambdaisland.regal :as regal]`             `;; [lambdaisland.regal.generator :as regal-gen]`             `))` and first few lines (def malli-opts {:registry {:regal regal-malli/regal-schema}}) (def form [:+ "y"]) (def schema (m/schema [:regal form] malli-opts)) (m/form schema) my namespace definition gives me Error: "No namespace: lambdaisland.regal.malli"... but works when I remove the :as m . Then it fails on the lambdaisland.regal.malli, and again works when :as regal-malli is removed... Finally if fails at (def malli-opts {:registry {:regal lambdaisland.regal.malli/regal-schema}}) with the error ; Syntax error (ClassNotFoundException) compiling at (h:\Work\Clojure\baseClj\src\baseClj\core.clj:55:1). ; lambdaisland.regal.malli . None of this makes any sense... this is just the example code. What am I missing?


I got a hint... The deps.edn include for malli was incorrect. I should have added metosin/malli {:mvn/version "0.5.1"} . This doesn't solve the problem tho...

ribelo23:06:28 is it dead or waiting for better times?