feat: :default-values-for-optional-keys for malli coercion

This commit is contained in:
Joel Kaasinen 2025-10-10 08:48:40 +03:00
parent 01766ee211
commit f26dc1ab19
3 changed files with 33 additions and 6 deletions

View file

@ -73,9 +73,10 @@ Using `create` with options to create the coercion instead of `coercion`:
{:transformers {:body {:default reitit.coercion.malli/default-transformer-provider
:formats {"application/json" reitit.coercion.malli/json-transformer-provider}}
:string {:default reitit.coercion.malli/string-transformer-provider}
:response {:default reitit.coercion.malli/default-transformer-provider}}
:response {:default reitit.coercion.malli/default-transformer-provider
:formats {"application/json" reitit.coercion.malli/json-transformer-provider}}}
;; set of keys to include in error messages
:error-keys #{:type :coercion :in :schema :value :errors :humanized #_:transformed}
:error-keys #{:type :coercion :in #_:schema :value #_:errors :humanized #_:transformed}
;; support lite syntax?
:lite true
;; schema identity function (default: close all map schemas)
@ -88,6 +89,10 @@ Using `create` with options to create the coercion instead of `coercion`:
:strip-extra-keys true
;; add/set default values
:default-values true
;; add/set defaults also for optional keys. Corresponds to :malli.transform/add-optional-keys
:default-values-for-optional-keys false
;; encode-error
:encode-error nil
;; malli options
:options nil})
```

View file

@ -9,8 +9,7 @@
[malli.swagger :as swagger]
[malli.transform :as mt]
[malli.util :as mu]
[reitit.coercion :as coercion]
[clojure.string :as string]))
[reitit.coercion :as coercion]))
;;
;; coercion
@ -27,11 +26,11 @@
(defn- -provider [transformer]
(reify TransformationProvider
(-transformer [_ {:keys [strip-extra-keys default-values]}]
(-transformer [_ {:keys [strip-extra-keys default-values default-values-for-optional-keys]}]
(mt/transformer
(if strip-extra-keys (mt/strip-extra-keys-transformer))
transformer
(if default-values (mt/default-value-transformer))))))
(if default-values (mt/default-value-transformer {:malli.transform/add-optional-keys default-values-for-optional-keys}))))))
(def string-transformer-provider (-provider (mt/string-transformer)))
(def json-transformer-provider (-provider (mt/json-transformer)))
@ -118,6 +117,8 @@
:strip-extra-keys true
;; add/set default values
:default-values true
;; add/set defaults also for optional keys. Corresponds to :malli.transform/add-optional-keys
:default-values-for-optional-keys false
;; encode-error
:encode-error nil
;; malli options

View file

@ -140,6 +140,27 @@
(let [m (r/match-by-path r "/none/kikka/abba")]
(is (= nil (coercion/coerce! m))))))))
(deftest malli-query-parameter-coercion-test
(let [router (fn [coercion]
(r/router ["/test"
{:coercion coercion
:parameters {:query [:map
[:a [:string {:default "a"}]]
[:x {:optional true} [:keyword {:default :a}]]]}}]
{:compile coercion/compile-request-coercers}))]
(testing "default values for :optional query keys do not get added"
(is (= {:query {:a "a"}}
(-> (r/match-by-path (router reitit.coercion.malli/coercion) "/test")
(assoc :query-params {})
(coercion/coerce!)))))
(testing "default values for :optional query keys get added when :default-values-for-optional-keys is set"
(is (= {:query {:a "a" :x :a}}
(-> (r/match-by-path (router (reitit.coercion.malli/create
(assoc reitit.coercion.malli/default-options
:default-values-for-optional-keys true))) "/test")
(assoc :query-params {})
(coercion/coerce!)))))))
(defn match-by-path-and-coerce! [router path]
(if-let [match (r/match-by-path router path)]
(assoc match :parameters (coercion/coerce! match))))