-
-
Notifications
You must be signed in to change notification settings - Fork 41
/
interceptors.cljc
104 lines (87 loc) · 4.38 KB
/
interceptors.cljc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
(ns martian.interceptors
(:require [martian.schema :as schema]
[clojure.walk :refer [stringify-keys]]
[clojure.string :as string]
[tripod.context :as tc]
[schema.core :as s]
[camel-snake-kebab.core :refer [->kebab-case-keyword]]
[martian.encoding :as encoding]
[martian.encoders :as encoders]))
(def request-only-handler
{:name ::request-only-handler
:leave (fn [ctx]
(-> ctx tc/terminate (dissoc ::tc/stack)))})
(defn- create-only [m k v]
(if (get m k)
m
(assoc m k v)))
(defn- insert-or-merge [m k v]
(cond
(get m k) (update m k #(merge v %))
(not-empty v) (assoc m k v)
:else m))
(def set-method
{:name ::method
:enter (fn [{:keys [handler] :as ctx}]
(update ctx :request create-only :method (:method handler)))})
(def set-url
{:name ::url
:enter (fn [{:keys [params url-for handler] :as ctx}]
(update ctx :request create-only :url (url-for (:route-name handler) params)))})
(defn coerce-data [{:keys [parameter-aliases] :as handler} schema-key params]
(schema/coerce-data (get handler schema-key) params parameter-aliases))
(def set-query-params
{:name ::query-params
:enter (fn [{:keys [params handler] :as ctx}]
(update ctx :request insert-or-merge :query-params (coerce-data handler :query-schema params)))})
(def set-body-params
{:name ::body-params
:enter (fn [{:keys [params handler] :as ctx}]
(if-let [[body-key body-schema] (first (:body-schema handler))]
(let [parameter-aliases (:parameter-aliases handler)
body-params (or (:martian.core/body params)
(get params (s/explicit-schema-key body-key))
(get params (->kebab-case-keyword (s/explicit-schema-key body-key)))
params)]
(update ctx :request insert-or-merge :body (schema/coerce-data body-schema body-params parameter-aliases)))
ctx))})
(def set-form-params
{:name ::form-params
:enter (fn [{:keys [params handler] :as ctx}]
(update ctx :request insert-or-merge :form-params (coerce-data handler :form-schema params)))})
(def set-header-params
{:name ::header-params
:enter (fn [{:keys [params handler] :as ctx}]
(update ctx :request insert-or-merge :headers (stringify-keys (coerce-data handler :headers-schema params))))})
(def enqueue-route-specific-interceptors
{:name ::enqueue-route-specific-interceptors
:enter (fn [{:keys [handler] :as ctx}]
(if-let [i (:interceptors handler)]
(update ctx ::tc/queue #(into (into tc/queue i) %))
ctx))})
(defn encode-body [encoders]
{:name ::encode-body
:enter (fn [{:keys [request handler] :as ctx}]
(let [content-type (and (:body request)
(not (get-in request [:headers "Content-Type"]))
(encoding/choose-content-type encoders (:consumes handler)))
{:keys [encode] :as encoder} (encoding/find-encoder encoders content-type)]
(cond-> ctx
(get-in ctx [:request :body]) (update-in [:request :body] encode)
content-type (assoc-in [:request :headers "Content-Type"] content-type))))})
(def default-encode-body (encode-body (encoders/default-encoders)))
(defn coerce-response [encoders]
{:name ::coerce-response
:enter (fn [{:keys [request handler] :as ctx}]
(let [content-type (and (not (get-in request [:headers "Accept"]))
(encoding/choose-content-type encoders (:produces handler)))
{:keys [as] :or {as :text}} (encoding/find-encoder encoders content-type)]
(cond-> (assoc-in ctx [:request :as] as)
content-type (assoc-in [:request :headers "Accept"] content-type))))
:leave (fn [{:keys [request response handler] :as ctx}]
(assoc ctx :response
(let [content-type (and (:body response)
(not-empty (get-in response [:headers :content-type])))
{:keys [matcher decode] :as encoder} (encoding/find-encoder encoders content-type)]
(update response :body decode))))})
(def default-coerce-response (coerce-response (encoders/default-encoders)))