diff --git a/src/clj_http/client.clj b/src/clj_http/client.clj index 8c38cf0c..b33dfdca 100644 --- a/src/clj_http/client.clj +++ b/src/clj_http/client.clj @@ -965,20 +965,32 @@ ([req respnd raise] (client (form-params-request req) respnd raise)))) +(defn- subscript [k i] + (str (name k) \[ i \])) + +(defn- unnest-1 [param-assoc] + (mapcat (fn [[k v]] + (if (sequential? v) + (map-indexed (fn [i sv] [(subscript k (str i)) sv]) v) + (map (fn [[i sv]] [(subscript k (name i)) sv]) (seq v)))) + param-assoc)) + +(defn- unnest-inner [param-assoc] + (let [{nested true flat false} (group-by (comp coll? second) param-assoc)] + (if (empty? nested) + param-assoc + (concat flat (unnest-inner (unnest-1 nested)))))) + +(defn- unnest [params] + (->> (seq params) + unnest-inner + (apply concat) + (apply hash-map))) + (defn- nest-params [request param-key] (if-let [params (request param-key)] - (assoc request param-key (prewalk - #(if (and (vector? %) (map? (second %))) - (let [[fk m] %] - (reduce - (fn [m [sk v]] - (assoc m (str (name fk) - \[ (name sk) \]) v)) - {} - m)) - %) - params)) + (assoc request param-key (unnest params)) request)) (defn- nest-params-request diff --git a/test/clj_http/test/client_test.clj b/test/clj_http/test/client_test.clj index d2c2c59b..7178b6ec 100644 --- a/test/clj_http/test/client_test.clj +++ b/test/clj_http/test/client_test.clj @@ -1272,6 +1272,14 @@ {:query-params {"a" {"b" {"c" "d"}}} :form-params {"a[b][c]" "d"} :flatten-nested-keys [:form-params]}) + (is-applied (comp client/wrap-form-params + client/wrap-nested-params) + {:query-params {"a" [{"c" "d"} "e"]} + :form-params {"a" [{"c" "d"} "e"]} + :flatten-nested-keys [:form-params]} + {:query-params {"a" [{"c" "d"} "e"]} + :form-params {"a[0][c]" "d" "a[1]" "e"} + :flatten-nested-keys [:form-params]}) (is-applied (comp client/wrap-form-params client/wrap-nested-params) {:query-params {"a" {"b" {"c" "d"}}}