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.
- BREAKING: remove map syntax:
mu/from-map-syntax
,mu/to-map-syntax
. Note that AST syntax and lite syntax remain unchanged. - BREAKING: walking a
:schema
with anid
no longer passes[id]
instead ofchildren
to the walker function #884 - Support converting recursive malli schemas to json-schema #464 #868
- Add cherry as alternative CLJS evaluator #888
- Replace
goog/mixin
withObject.assign
#890 - Simplify uuid regex for accept non-standard and zero uuids #889
- Fix clj-doc API import #887
- FIX
malli.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}
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
)- Simplify content-dependent schema creation with
m/-simple-schema
andm/-collection-schema
via new 3-arity:compile
function of typechildren properties options -> props
. Old 2-arity top-level callback function ism/deprecated!
and support for it will be removed in future versions. #866 - FIX Repeated calls to
malli.util/assoc-in
referencing non-existing maps fail #874 - Updated dependencies:
borkdude/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
andm/-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
- Strip-extra-keys should not break on non-map values #818
- New optional time-schemas for the JVM on top of
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
- automatic type inferring with
:enum
and:=
withmalli.transform
andmalli.json-schema
- detects homogenous:string
,:keyword
,:symbol
,:int
and:double
), #782 & #784 - New
malli.core/coercer
andmalli.core/coerce
to both decode and validate a value, see Docs - New
malli.core/-no-op-transformer
- BREAKING: new implemenation for
:map-of
inferring viamalli.provider/provide
:- Option
:malli.provider/map-of-threshold
default dropped (was 3) - New and configurable (
malli.provider/map-of-accept
) function ofstats -> boolean
for identifying:map-of
- Option
- BREAKING: Prefer to real Schemas instead of predicates in inferring (e.g.
:int
over'int?
) - Adds
:pred
option tom/-map-schema
#767 - New
:some
schema (likesome?
) - New
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"
- Fix report-fn fn-name symbol constructor in instrument #768
- Fix instrument! in dev.cljs/start! - pass cljs function schemas #766
- Improve regex driver cache performance #756
- Refactor cljs fn instrumentation to happen at runtime #755
- Add jdk 19 to ci #760
- Fix pos? json schema mapping #757
- Generate alphanumeric strings with
:min/:max
#759 - Add cljs instrumentation support for multi-arity and varargs functions #753
- Attach fn-name metadata to instrumented CLJS functions #746
- Improve generator distribution for sized schemas #748
- Group instrumentation logging so it doesn't spam the browser console #747
- Fix recursive gen #677, fixed On fixing Malli's recursive generation
- Mask valid values by default with
malli.dev.pretty/explain
#738 - Add seq to tuple transformation #735, fixes #734
- Switch Value and Errors in the pretty output order, #720
- Ensure all examples work without sci unless mentioned otherwise #733
- Set additionalProperties if map is closed #719, fixes #716
- Fix registry lookup in schema vector syntax, #729, fixes #451
- Source-compatible with nbb, #726
- Initial Development Guide
- Better humanized results with sets
::m/extra-key
error retains the error value- New
malli.error/error-value
utility for compact error value presentation. - BREAKING:
me/-push
takes extra argument - BREAKING:
me/-assoc-in
is now calledme/-push-in
- Updated dependencies:
borkdude/dynaload 0.3.4 -> 0.3.5
borkdude/dynaload 0.2.2 -> 0.3.4
- new guide for Static type checking via Typed Clojure
- new guide for To and from JSON
- much improved support for instrumentation & type checking with ClojureScript via #660, #661, #662, #667, #681, #685, #696, #697, #700, #703
- new
malli.dev.pretty/prettier
helper, [#672] - faster stripping away extra keys from maps, #674
- fix regex unparsing, [#690]
- fix Warning under advanced compilation via #692
- Map :re schema to clj-kondo :string
- added
mall.util/explain-data
,malli.util/data-explainer
andmalli.util/keys
#707 - fix mu/open-schema does not open a closed schema via #709
- Show function input arguments on invalid return value
- fix Don't lose properties when updating a key
malli.transform/default-value-transformer
acceptsmt/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"}
- updated dependencies:
fipp/fipp 0.2.5 -> 0.2.6
borkdude/edamame 0.0.18 -> 1.0.0
- technical redeploy
- technical redeploy
- technical redeploy
- support for 2-arity
default-fn
option inmt/default-value-transformer
#582 & #644 - fix malli.dev.cljs implementation #655
- FIX: qualified-keyword with namespace doesn't generate the ns #642
- new ns,
malli.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?]}}
- updated deps:
borkdude/edamame 0.0.18 -> 0.0.19
- FIX: bug in inferring with value encoders #631
- FIX: The malli pretty printer (virhe) is failing when it tries to print a datomic dbwhen it tries to pr #629
-
new
malli.instrument.cljs
andmalli.dev.cljs
namespaces for instrumentationa and dev-tooling for ClojureScript -
malli.dev/start!
usesmalli.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]]
- new
malli.experimental
namespace with schematizeddefn
, automatically registers the functions schemas withm/=>
.
(require '[malli.experimental :as mx])
(mx/defn kakka :- :int
"inline schemas (plumatic-style)"
[x :- :int] (inc x))
- transformer names can be qualified, schema properties support
: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
- updated dependencies:
fipp/fipp 0.6.24 -> 0.6.25
- clj-kondo 2021.12.16+ can load malli type configs automatically from new location (
.clj-kondo/metosin/malli-types/config.edn
) - use fipp for fast pretty-printing the clj-kondo configs
- updated dependencies:
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
- schema inferring supports value decoding via options
(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?]
- FIX Function with Sequential return value cannot define as function schema #585
- FIX
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}
- BREAKING:
m/explain
:errors
are plain maps, notError
records. - BREAKING:
malli.provider/schema
is moved into extender API:malli.provider/-schema
- BREAKING: strings generate alphanumeric chars by default
malli.provider
supports inferring of:maybe
and:map-of
- configure default registry in less invasive manner, #488
nil
is a valid default withmt/default-value-transformer
#576- fixed
:schema
explain path, #573 - fixed
:enum
explain path, #553 - fixed pretty printing of function values, #509
- fixed
:function
lenses - fixed arity error in
m/function-schema
- add localized error messages for all type-schemas
- support for Lazy EntrySchema parsing
empty?
Schema does not throw exceptions
- BREAKING:
m/EntrySchema
replacesm/MapSchema
with new-entry-parser
method - BREAKING: (eager)
m/-parse-entries
is removed, usem/-entry-parser
instead - BREAKING:
m/-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 andm/-create-cache
for memoization of-validator
,-explainer
,-parser
and-unparser
when usingm/validator
,m/explain
,m/parser
andm/unparser
.
- add missing optional dependency to
mvxcvi/arrangement
to make pretty printing work
- Much faster validators on CLJ (loop unrolling & programming against interfaces) with
: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)))
- Much faster collection transformers on CLJ (loop unrolling & programming against interfaces):
(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 ofmalli.core/-unlift-keys
-
BREAKING:
malli.json-schema/unlift
is removed in favor ofget
-
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
andmalli.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 anddefn
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]/(metosin#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"]}
- New experimental pretty printer for schema errors, using fipp.
malli.util.impl/-fail!
is nowmalli.core/-fail!
malli.core/-unlift-keys
malli.core/-instrument
- BREAKING:
malli.core/-register-function-schema!
is now 4-arity, new argument is data map - BREAKING:
malli.core/-fail!
has only arity 1 & 2 versions
- Fix #435: :re ignores :gen/xxx properties in absence of :gen/gen
- More customization on -collection-schema #433
- Add
ifn?
predicate, #416 - Accumulate errors correctly with
m/-explain
with:function
and:=>
Schemas - New
m/properties-schema
andm/children-schema
to resolve Malli Schemas forIntoSchema
s. Empty implementations. - New
:gen/schema
property for declarative generation, e.g.[:string {:gen/schema :int, :gen/fmap str}]
- Support double generator options via schema properties
- Fix #419: Parsing bug in :map schema
- Fix #418: Better error messages / docs for registry references
- Fix #415: Default branch in multi schema are not transformed
- Fix #427: Generated sets of :ref are always empty
- BREAKING:
-type
is moved fromSchema
toIntoSchema
. - BREAKING:
-type-properties
is moved fromSchema
toIntoSchema
. - new Protocol methods in
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- BREAKING/FIX: parsing
:multi
returns branch information, #403 :and
merges using first child, #405
- Add
:orn
json-schema & generator, #400 - Ignore optional properties in
mt/default-value-transformer
, #397 - Support
nil
keys in maps, #392 :m/default
for:multi
, #391- Fix inconsistent park-ing in alt(n)-parser, #390
- Fix json schema generation when all attributes of a map are optional, #385
- Note about transformers best-effort behavior, #384
- Humanized regex/sequence errors, #383
- Humanized error for
:double
, #382
-
support for sequence schemas:
:cat
,catn
,alt
,altn
,:?
,:*
,:+
andrepeat
, 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
- BREAKING:
m/Schema
has new methods:-parent
,-parser
and-unparser
- BREAKING:
m/-coder
andm/-chain
are replaced wihm/-intercepting
- BREAKING:
m/-fail!
is nowmiu/-fail!
- BREAKING:
m/-error
is nowmiu/-error
- fix
:sequential
decoding with empty sequence undermt/json-transformer
, fixes #288- removed broken
mt/-sequential->seq
- removed broken
- BREAKING (MINOR):
m/deref
returns original schema, does not throw, fixes #284. - BREAKING (MINOR): the following utilities in
malli.util
deref top-level refs recursively:merge
,union
,transform-entries
,optional-keys
,required-keys
,select-keys
anddissoc
. 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
.- Welcome declarative schema transformations!
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 disablingsci
, fixes #276:malli.core/sci-options
for configuringsci
-
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 "-"}}
- Support microsecond precision when parsing datetime strings. #280
First stable release.
- 8.10.2020
- removed
:list
schema - removed
malli.error/SchemaError
protocol in favor of usingm/type-properties
for custom errors
- removed
- 20.9.2020
- removed
m/-predicate-schema
,m/-partial-predicate-schema
andm/-leaf-schema
- removed
- 19.9.2020
- new mandatory Protocol method in
m/Schema
:-type-properties
- new mandatory Protocol method in
- 1.9.2020
m/children
returns 3-tuple (key, properties, schema) forMapSchema
sm/map-entries
is removed,m/entries
returns aMapEntry
of key &m/-val-schema
- 4.8.2020
:path
in explain is re-implemented: map keys by value, others by child indexm/-walk
andm/Walker
uses:path
, not:in
m/-outer
has new parameter order:walker schema path children options
malli.util/path-schemas
replaced withmalli.util/subschemas
&malli.util/distict-by
LensSchema
has a new-key
method- renamed some non-user apis in
malli.core
&malli.util
- moved map-syntax helpers from
malli.core
tomalli.util
- dynaload
com.gfredericks/test.chuck
- 23.7.2020
sci
is not a default dependency. Enabling sci-support:- Clojure: add a dependency to
borkdude/sci
- ClojureScript: also require
sci.core
(directly or via:preloads
)
- Clojure: add a dependency to
- 18.7.2020
- big cleanup of
malli.transform
internals.
- big cleanup of
- 12.7.2020
malli.mermaid
is removed (in favor ofmalli.dot
)
- 10.7.2020
[metosin/malli "0.0.1-20200710.075225-19"]
- Visitor is implemented using a Walker.
m/accept
->m/walk
m/schema-visitor
->m/schema-walker
m/map-syntax-visitor
->m/map-syntax-walker
- 31.6.2020
- new
-children
method inSchema
, to return child schemas as instances (instead of just AST)
- new
- 17.6.2020
- change all
malli.core/*-registry
defs intomalli.core/*-schemas
defns to enable DCE for clojurescript
- change all
- 9.6.2020
malli.core/name
&malli.core/-name
renamed tomalli.core/type
&malli.core/-type
malli.generator/-generator
is renamed tomalli.generator/-schema-generator