We use Break Versioning. The version numbers follow a <major>.<minor>.<patch> scheme with the following intent:
| Bump | Intent |
|---|---|
major | Major breaking changes -- check the changelog for details. |
minor | Minor breaking changes -- check the changelog for details. |
patch | No breaking changes, ever!! |
-SNAPSHOT versions are preview versions for upcoming releases.
Malli is in well matured alpha.
(m/validate
[:map
[:x :int]
[:y :int]
[::m/default [:map-of :string :string]]]
{:x 1, :y 2, "kikka" "kukka"})
; => true
mt/strip-extra-keys-transformer works with :map-of.(m/decode
[:map-of :int :int]
{1 1, 2 "2", "3" 3, "4" "4"}
(mt/strip-extra-keys-transformer))
; => {1 1}
m/default-schema to pull the ::m/default schema from entry schemasm/explicit-keys to get a vector of explicit keys from entry schemas (no ::m/default)m/-simple-schema and m/-collection-schema via new 3-arity :compile function of type children properties options -> props. Old 2-arity top-level callback function is m/deprecated! and support for it will be removed in future versions. #866malli.util/assoc-in referencing non-existing maps fail #874borkdude/edamame 1.1.17 -> 1.3.20
Implement malli.experimental.time schemas for clojurescript using js-joda #853
Allow instrumenting external functions #841
Add clj-kondo support for cljs function schemas #833
Turn on instrumentation for mx/defn with :malli/always meta #825
Support type-properties in m/-map-schema, m/-map-of-schema and m/-tuple-schema #856
FIX: properly compose interceptors in :map-of json-transformer #849
FIX: error paths for :multi schemas when value is not a map #845
FIX: Malli generates :nilable/any which is not a valid type in clj-kondo #821
FIX: mi/collect! without args doesn't work properly #834
Updated dependencies:
mvxcvi/mvxcvi 2.0.0 -> 2.1.0
borkdude/edamame 1.0.0 -> 1.1.17
java.time:
:time/duration, :time/instant, :time/local-date, :time/local-date-time, :time/local-time, :time/offset-date-time, :time/offset-time, :time/zone-id, :time/zone-offset, :time/zoned-date-time, see README:enum and := with malli.transform and malli.json-schema - detects homogenous :string, :keyword, :symbol, :int and :double), #782 & #784malli.core/coercer and malli.core/coerce to both decode and validate a value, see Docsmalli.core/-no-op-transformer:map-of inferring via malli.provider/provide:
:malli.provider/map-of-threshold default dropped (was 3)malli.provider/map-of-accept) function of stats -> boolean for identifying :map-of:int over 'int?):pred option to m/-map-schema #767:some schema (like some?)malli.experimental.describe to describe Schemas in english:* (require '[malli.experimental.describe :as med])
(med/describe [:map {:closed true} [:x int?]])
; => "map where {:x -> <integer>} with no other keys"
:min/:max #759malli.dev.pretty/explain #738::m/extra-key error retains the error valuemalli.error/error-value utility for compact error value presentation.me/-push takes extra argumentme/-assoc-in is now called me/-push-inborkdude/dynaload 0.3.4 -> 0.3.5
borkdude/dynaload 0.2.2 -> 0.3.4
malli.dev.pretty/prettier helper, [#672]mall.util/explain-data, malli.util/data-explainer and malli.util/keys #707malli.transform/default-value-transformer accepts mt/add-optional-keys option:(m/decode
[:map
[:name [:string {:default "kikka"}]]
[:description {:optional true} [:string {:default "kikka"}]]]
{}
(mt/default-value-transformer {::mt/add-optional-keys true}))
; => {:name "kikka", :description "kikka"}
fipp/fipp 0.2.5 -> 0.2.6
borkdude/edamame 0.0.18 -> 1.0.0
default-fn option in mt/default-value-transformer #582 & #644malli.experimental.lite, see the docs.(require '[malli.experimental.lite :as l])
{:id string?
:tags [:set keyword?]
:address {:street string?
:city string?
:zip (l/optional int?)
:lonlat [:tuple double? double?]}}
borkdude/edamame 0.0.18 -> 0.0.19
new malli.instrument.cljs and malli.dev.cljs namespaces for instrumentationa and dev-tooling for ClojureScript
malli.dev/start! uses malli.dev.pretty/reporter by default
allow :malli/schema to be defined via arglist meta-data, #615
BREAKING: local registries with schemas in vector syntax are stored as identity, not as form
BREAKING: :malli.provider/tuple-threshold has no default value
FIX: me/-resolve-root-error does not respect :error/path, #554
FIX: m/from-ast does not work with symbols or unamespaced keywords, #626
FIX: :+ parsing returns vector, not sequence
new malli.destructure ns for parsing Clojure & Plumatic destructuring binding syntaxes, see Destructuring.
(require '[malli.destructure :as md])
(-> '[a b & cs] (md/parse) :schema)
; => [:cat :any :any [:* :any]]
(-> '[a :- :string, b & cs :- [:* :int]] (md/parse) :schema)
; => [:cat :string :any [:* :int]]
malli.experimental namespace with schematized defn, automatically registers the functions schemas with m/=>.(require '[malli.experimental :as mx])
(mx/defn kakka :- :int
"inline schemas (plumatic-style)"
[x :- :int] (inc x))
:decode and :encode keys:(m/decode
[:string {:decode {:string (partial str "olipa "}}]
"kerran" mt/string-transformer)
; => "olipa kerran"
malli.dev.pretty/explain for pretty-printing explanations
fipp/fipp 0.6.24 -> 0.6.25
.clj-kondo/metosin/malli-types/config.edn)mvxcvi/arrangement 1.2.0 -> 2.0.0
borkdude/edamame 0.0.11 -> 0.0.18
org.clojure/test.check 1.1.0 -> 1.1.1
(mp/provide
[{:id "caa71a26-5fe1-11ec-bf63-0242ac130002"}
{:id "8aadbf5e-5fe3-11ec-bf63-0242ac130002"}]
{::mp/value-decoders {'string? {:uuid mt/-string->uuid}}})
; => [:map [:id :uuid]]
:map-of inferring can be forced with :malli.provider/hint :map-of meta-data:(require '[malli.provider :as mp])
(mp/provide
[^{::mp/hint :map-of}
{:a {:b 1, :c 2}
:b {:b 2, :c 1}
:c {:b 3}
:d nil}])
;[:map-of
; keyword?
; [:maybe [:map
; [:b int?]
; [:c {:optional true} int?]]]]
:tuple inferring (supports type-hints and threshold options)(mp/provide
[[1 "kikka" true]
[2 "kukka" true]
[3 "kakka" true]]
{::mp/tuple-threshold 3})
; [:tuple int? string? boolean?]
decimal? predicate schema was removed in 0.7.0, #590(def ?schema
[:map
[:x boolean?]
[:y {:optional true} int?]
[:z [:map
[:x boolean?]
[:y {:optional true} int?]]]])
(def schema (m/schema ?schema))
;; 44µs -> 2.5µs (18x)
(bench (m/schema ?schema))
;; 44µs -> 240ns (180x, not realized)
(p/bench (m/schema ?schema {::m/lazy-entries true}))
;; 26µs -> 1.2µs (21x)
(bench (m/walk schema (m/schema-walker identity)))
;; 4.2µs -> 0.54µs (7x)
(bench (mu/assoc schema :w :string))
;; 51µs -> 3.4µs (15x)
(bench (mu/closed-schema schema))
;; 5µs -> 28ns (180x)
(p/bench (m/deref-all ref-schema))
;; 134µs -> 9µs (15x)
(p/bench (mu/merge schema schema))
(def schema (m/schema ?schema))
;; 1.6µs -> 64ns (25x)
(p/bench (m/validate schema {:x true, :z {:x true}}))
;; 1.6µs -> 450ns (3x)
(p/bench (m/explain schema {:x true, :z {:x true}}))
(def samples
[{:id "Lillan"
:tags #{:artesan :coffee :hotel}
:address {:street "Ahlmanintie 29"
:city "Tampere"
:zip 33100
:lonlat [61.4858322, 23.7854658]}}
{:id "Huber",
:description "Beefy place"
:tags #{:beef :wine :beer}
:address {:street "Aleksis Kiven katu 13"
:city "Tampere"
:zip 33200
:lonlat [61.4963599 23.7604916]}}])
;; 126ms -> 2.5ms (50x)
(p/bench (mp/provide samples))
;; 380µs (330x)
(let [provide (mp/provider)]
(p/bench (provide samples)))
New optimized map-syntax to super-fast schema creation, see README.
(def ast (m/ast ?schema))
;{:type :map,
; :keys {:x {:order 0, :value {:type boolean?}},
; :y {:order 1, :value {:type int?}
; :properties {:optional true}},
; :z {:order 2,
; :value {:type :map,
; :keys {:x {:order 0
; :value {:type boolean?}},
; :y {:order 1
; :value {:type int?}
; :properties {:optional true}}}}}}}
;; 150ns (16x)
(p/bench (m/from-ast ast))
(-> ?schema
(m/schema)
(m/ast)
(m/from-ast)
(m/form)
(= ?schema))
; => true
Currently in alpha, will fully replace the old map-syntax at some point.
No need to play with Compiler options or JVM properties to swap the default registry (only if you want to get DCE on CLJS with small set of schemas). Can be disabled with new malli.registry/mode=strict option.
(require '[malli.core :as m]
'[malli.util :as mu]
'[malli.registry :as mr]
'[malli.generator :as mg])
;; look ma, just works
(mr/set-default-registry!
(mr/composite-registry
(m/default-schemas)
(mu/schemas)))
(mg/generate
[:merge
[:map [:x :int]]
[:map [:y :int]]])
; => {:x 0, :y 92}
m/explain :errors are plain maps, not Error records.malli.provider/schema is moved into extender API: malli.provider/-schemamalli.provider supports inferring of :maybe and :map-ofnil is a valid default with mt/default-value-transformer #576:schema explain path, #573:enum explain path, #553:function lensesm/function-schemaempty? Schema does not throw exceptionsm/EntrySchema replaces m/MapSchema with new -entry-parser methodm/-parse-entries is removed, use m/-entry-parser insteadm/-create-form supports 2 & 4 arities (was: 3)m/EntryParser protocolm/-entry-forms helperm/walk-leaf, m/-walk-entries & m/-walk-indexed helpersm/Cached protocol and m/-create-cache for memoization of -validator, -explainer, -parser and -unparser when using m/validator, m/explain, m/parser and m/unparser.mvxcvi/arrangement to make pretty printing work:or, :and, :orn and :map, thanks to Ben Sless:;; 164ns -> 28ns
(let [valid? (m/validator [:and [:> 0] [:> 1] [:> 2] [:> 3] [:> 4]])]
(cc/quick-bench (valid? 5)))
;; 150ns -> 30ns
(let [valid? (m/validator [:map [:a :any] [:b :any] [:c :any] [:d :any] [:e :any]])
value {:a 1, :b 2, :c 3, :d 4, :e 5}]
(cc/quick-bench (valid? value)))
(let [decode (m/decoder
[:map
[:id :string]
[:type :keyword]
[:address
[:map
[:street :string]
[:lonlat [:tuple :double :double]]]]]
(mt/json-transformer))
json {:id "pulla"
:type "food"
:address {:street "hämeenkatu 14"
:lonlat [61 23.7644223]}}]
;; 920ns => 160ns
(cc/quick-bench
(decode json)))
BREAKING: malli.json-schema/unlift-keys is removed in favor of malli.core/-unlift-keys
BREAKING: malli.json-schema/unlift is removed in favor of get
BREAKING: malli.provider/stats is removed (was already deprecated)
BREAKING: malli.util/update doesn't the properties of the key it updates, fixes #412
BREAKING: New rules for humanized errors, see #502, fixes #80, #428 and #499.
new malli.instrument and malli.dev for instrumenting function Vars (e.g. defns), see the guide.
new malli.plantuml namespace for PlantUML generation
new malli.generator/check for generative testing of functions and defns.
new malli.core/parent
:map-of supports :min and :max properties
Collection Schemas emit correct JSON Schema min & max declarations
humanized errors for :boolean & :malli.core/tuple-limit
predicate schema for fn?
malli.util/transform-entries passes in options [#340]/(https://github.com/metosin/malli/pull/340)
BETA: humanized errors can be read from parent schemas (also from map entries), fixes #86:
(-> [:map
[:foo {:error/message "entry-failure"} :int]]
(m/explain {:foo "1"})
(me/humanize {:resolve me/-resolve-root-error}))
; => {:foo ["entry-failure"]}
malli.util.impl/-fail! is now malli.core/-fail!malli.core/-unlift-keysmalli.core/-instrumentmalli.core/-register-function-schema! is now 4-arity, new argument is data mapmalli.core/-fail! has only arity 1 & 2 versionsifn? predicate, #416m/-explain with :function and :=> Schemasm/properties-schema and m/children-schema to resolve Malli Schemas for IntoSchemas. Empty implementations.:gen/schema property for declarative generation, e.g. [:string {:gen/schema :int, :gen/fmap str}]-type is moved from Schema to IntoSchema.-type-properties is moved from Schema to IntoSchema.IntoSchema Protocol
(-properties-schema [this options] "maybe returns :map schema describing schema properties")(-children-schema [this options] "maybe returns sequence schema describing schema children"):nil schema, #401:multi returns branch information, #403:and merges using first child, #405:orn json-schema & generator, #400mt/default-value-transformer, #397nil keys in maps, #392:m/default for :multi, #391:double, #382support for sequence schemas: :cat, catn, alt, altn, :?, :*, :+ and repeat, see Sequence Schemas.
support for parsing and unparsing schemas: m/parse, m/parser, m/unparse, m/unparser, see Parsing values.
support for function schmas: :=> and :function, see Function Schemas.
new schemas: :any (e.g. any?), :not (complement) and :orn (or with named branches)
:qualified-keyword support :namespace property
FIX: Schema vizualization is not working for [:< ...] like schemas, #370
Ensure we use size 30 for generator (for more variety), #364
Set JSON Schema types and formats for numbers properly #354
-memoize actually memoized. easily 100x faster now #350
Fix interceptor composition, #347
malli.util: add a rename-keys utility, similar to clojure.set #338
Let mu/update accept plain data schemas, #329
mu/find, #322
m/Schema has new methods: -parent, -parser and -unparserm/-coder and m/-chain are replaced wih m/-interceptingm/-fail! is now miu/-fail!m/-error is now miu/-error:sequential decoding with empty sequence under mt/json-transformer, fixes #288
mt/-sequential->seqm/deref returns original schema, does not throw, fixes #284.malli.util deref top-level refs recursively: merge, union, transform-entries, optional-keys, required-keys, select-keys and dissoc.m/deref-all derefs all top-level references recursively, e.g.(m/deref-all [:schema [:schema int?]])
; => int?
:ref, :schema, ::m/schema have now generators, JSON Schema and Swagger supportmu/subschemas walks over top-level :ref and all :schemas.m/walk can walk over :ref and :schema reference schemas. Walking can be enabled using options :malli.core/walk-refs and :malli.core/walk-schema-refs.There are also declarative versions of schema transforming utilities in malli.util/schemas. These include :merge, :union and :select-keys:
(def registry (merge (m/default-schemas) (mu/schemas)))
(def Merged
(m/schema
[:merge
[:map [:x :string]]
[:map [:y :int]]]
{:registry registry}))
Merged
;[:merge
; [:map [:x :string]]
; [:map [:y :int]]]
(m/deref Merged)
;[:map
; [:x :string]
; [:y :int]]
(m/validate Merged {:x "kikka", :y 6})
; => true
New options for SCI:
:malli.core/disable-sci for explicitly disabling sci, fixes #276:malli.core/sci-options for configuring scimalli.transform/default-value-transformer accepts options :key and :defaults:
(m/decode
[:map
[:user [:map
[:name :string]
[:description {:ui/default "-"} :string]]]]
nil
(mt/default-value-transformer
{:key :ui/default
:defaults {:map (constantly {})
:string (constantly "")}}))
; => {:user {:name "", :description "-"}}
First stable release.
:list schemamalli.error/SchemaError protocol in favor of using m/type-properties for custom errorsm/-predicate-schema, m/-partial-predicate-schema and m/-leaf-schemam/Schema: -type-propertiesm/children returns 3-tuple (key, properties, schema) for MapSchemasm/map-entries is removed, m/entries returns a MapEntry of key & m/-val-schema:path in explain is re-implemented: map keys by value, others by child indexm/-walk and m/Walker uses :path, not :inm/-outer has new parameter order: walker schema path children optionsmalli.util/path-schemas replaced with malli.util/subschemas & malli.util/distict-byLensSchema has a new -key methodmalli.core & malli.utilmalli.core to malli.utilcom.gfredericks/test.chucksci is not a default dependency. Enabling sci-support:
borkdude/scisci.core (directly or via :preloads)malli.transform internals.malli.mermaid is removed (in favor of malli.dot)[metosin/malli "0.0.1-20200710.075225-19"]m/accept -> m/walkm/schema-visitor -> m/schema-walkerm/map-syntax-visitor -> m/map-syntax-walker-children method in Schema, to return child schemas as instances (instead of just AST)malli.core/*-registry defs into malli.core/*-schemas defns to enable DCE for clojurescriptmalli.core/name & malli.core/-name renamed to malli.core/type & malli.core/-typemalli.generator/-generator is renamed to malli.generator/-schema-generatorCan you improve this documentation? These fine people already did:
Tommi Reiman, Miikka Koskinen, Joel Kaasinen, James Conroy-Finn & Lucy WangEdit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |