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.
:->
for simpler function defintions (not available on default schema registry) #1027[:-> :any] ; [:=> :cat :any]
[:-> :int :any] ; [:=> [:cat :int] :any]
[:-> [:cat :int] :any] ; [:=> [:cat [:cat :int]] :any]
[:-> a b c d :any] ; [:=> [:cat a b c d] :any]
;; guard property
[:-> {:guard (fn [[[arg] ret]] ...)} :string :boolean]
; [:=> [:cat :string] :boolean [:fn (fn [[[arg] ret]] ...)]]
mu/get-in
for false-y keys #1065:float
#1055:double
generates Long if :
min is Long #1034:malli.json-schema/definitions-path
#1045:body
swagger parameters #1044mu/update-entry-properties
#1037:min
/ :max
when different #1032:map-of
:min
and unreachable generator, explain such-that failures #1029:=>
takes optional 3rd child, the guard schema validating vector of arguments and return value [args ret]
. See Function Guards for more details. Fixes #764 and #764.;; function of arg:int -> ret:int, where arg < ret
[:=>
[:cat :int]
:int
[:fn (fn [[[arg] ret]] (< arg ret))]]
BREAKING: malli.generator/function-checker
returns explanations under new keys:
::mg/explain-input
-> ::m/explain-input
::mg/explain-output
-> ::m/explain-output
::m/explain-guard
to return guard explanation, if anym/explain
for :=>
returns also errors for args, return and guard if they exist
FIX m/deref-recursive
doesn't play nice with :merge
schema #997 via #999
FIX nested :repeat
sequence schema's doesn't seem to work #761 via #1024
FIX Invalid Swagger JSON with [:or :nil]
alternatives #1006 via #1023
FIX (explain :tuple [])
#1022
Enforce entry specs in open map destructurings #1021
FIX goog/mixin
was deprecated and is now removed #1016
Updated dependencies:
borkdude/edamame 1.3.23 -> 1.4.25
m/deref-recursive
to recursive deref all schemas (not :ref
s)m/coerce
and m/coercer
throw ::m/coercion
instead of ::m/invalid-input
mt/strip-extra-keys-transformer
for recursive map encoding #963:type
in into-schema opt for :map
and :map-of
#968mu/path->in
works with :orn
, :catn
and :altn
.:or
and :orn
, #946decode
for :double
and double?
in cljs doesn't allow trailing garbage any more #942:map
, #948 & #949:altn
can't handle just one child entry when nested in sequence schema #945bound-fn
in malli.dev/start!
to preserve *out*
#954malli.experimental.describe
descriptions of :min
and :max
are backwards #959:catn
unparse, fixes #925malli.experimental.time
malli.core/-comp
keeps interceptor order with long chains #905malli.dev/start!
exception does not contain source #896:gen/return
support in malli.generator #933:default/fn
prop for default-value-transformer #927borkdude/edamame 1.3.20 -> 1.3.23
mu/from-map-syntax
, mu/to-map-syntax
. Note that AST syntax and lite syntax remain unchanged.:schema
with an id
no longer passes [id]
instead of children
to the walker function #884goog/mixin
with Object.assign
#890malli.swagger
ns, broken test on reitit.(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}
mt/strip-extra-keys-transformer
strips non-defined keys of implicitely open :map
:(m/decode
[:map [:x :int]]
{:x 1, :y 2, :z 3}
(mt/strip-extra-keys-transformer))
; => {:x 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-in
borkdude/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 explanationsfipp/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/-schema
malli.provider
supports inferring of :maybe
and :map-of
nil
is a valid default with mt/default-value-transformer
#576:schema
explain path, #573:enum
explain path, #553:function
lensesm/function-schema
empty?
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. defn
s), see the guide.
new malli.plantuml
namespace for PlantUML generation
new malli.generator/check
for generative testing of functions and defn
s.
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-keys
malli.core/-instrument
malli.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 IntoSchema
s. 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 -unparser
m/-coder
and m/-chain
are replaced wih m/-intercepting
m/-fail!
is now miu/-fail!
m/-error
is now miu/-error
:sequential
decoding with empty sequence under mt/json-transformer
, fixes #288
mt/-sequential->seq
m/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 :schema
s.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 sci
malli.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-schema
m/Schema
: -type-properties
m/children
returns 3-tuple (key, properties, schema) for MapSchema
sm/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 :in
m/-outer
has new parameter order: walker schema path children options
malli.util/path-schemas
replaced with malli.util/subschemas
& malli.util/distict-by
LensSchema
has a new -key
methodmalli.core
& malli.util
malli.core
to malli.util
com.gfredericks/test.chuck
sci
is not a default dependency. Enabling sci-support:
borkdude/sci
sci.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/walk
m/schema-visitor
-> m/schema-walker
m/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/-type
malli.generator/-generator
is renamed to malli.generator/-schema-generator
Can you improve this documentation? These fine people already did:
Tommi Reiman, Joel Kaasinen, Miikka Koskinen, James Conroy-Finn & Lucy WangEdit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close