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 alpha.
(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
Will fully replace the old map-syntax at some point.
- 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:
malli.provider/schema
is moved into extender API:malli.provider/-schema
- BREAKING: strings generate alphanumeric chars by default
- 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