/
easy.cljc
116 lines (104 loc) · 4.31 KB
/
easy.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
105
106
107
108
109
110
111
112
113
114
115
116
(ns ajax.easy
(:require [ajax.simple :as simple]
[ajax.transit :as t]
[ajax.json :as json]
[ajax.ring :as ring]
[ajax.url :as url]
[ajax.formats :as f]))
(def default-formats
(atom
[["application/transit+json" t/transit-response-format]
["application/transit+transit" t/transit-response-format]
["application/json" json/json-response-format]
["text/plain" f/text-response-format]
["text/html" f/text-response-format]
["*/*" f/raw-response-format]]))
(defn detect-response-format
([] (f/detect-response-format {:response-format @default-formats}))
([opts] (f/detect-response-format opts)))
(defn keyword-request-format [format format-params]
"Converts an easy API request format specifier to an `ajax-request`
request format specifier."
(cond
(map? format) format
(fn? format) {:write format}
(nil? format) (t/transit-request-format format-params)
:else (case format
:transit (t/transit-request-format format-params)
:json (json/json-request-format)
:text (f/text-request-format)
:raw (url/url-request-format format-params)
:url (url/url-request-format format-params)
nil)))
(defn- keyword-response-format-element [format format-params]
(cond
(vector? format) [(first format)
(keyword-response-format-element (second format)
format-params)]
(map? format) format
(fn? format) {:read format :description "custom"}
(nil? format) (detect-response-format)
:else (case format
:transit (t/transit-response-format format-params)
:json (json/json-response-format format-params)
:text (f/text-response-format)
:ring (ring/ring-response-format)
:raw (f/raw-response-format)
:detect (detect-response-format)
nil)))
(defn keyword-response-format [format format-params]
"Converts an easy API format specifier to an `ajax-request`
format specifier. Mostly this is just a case of replacing `:json`
with `json-response-format`. However, it gets complex when you
specify a detection format such as `[[\"application/madeup\" :json]]`."
(if (vector? format)
(->> format
(map #(keyword-response-format-element % format-params))
(apply vector))
(keyword-response-format-element format format-params)))
(defn print-response [response]
(println "CLJS-AJAX response:" response))
(def default-handler
"This gets called if you forget to attach a handler to an easy
API function."
(atom print-response))
(defn print-error-response [response]
#? (:clj (println "CLJS-AJAX ERROR:" response)
:cljs (cond (exists? js/console) (.error js/console response)
(exists? js/window) (.alert js/window (str response))
:else (println "CLJS-AJAX ERROR:" response))))
(def default-error-handler
"This will be called when errors occur if you don't supply
an error handler to the easy API functions. If you don't
want it writing errors to the console (or worse, flashing up
alerts), make sure you always handle errors."
(atom print-error-response))
(defn transform-handler
"Converts easy API handlers to a `ajax-request` handler"
[{:keys [handler error-handler finally]}]
(let [h (or handler @default-handler)
e (or error-handler @default-error-handler)]
(fn easy-handler [[ok result]]
((if ok h e) result)
(when (fn? finally)
(finally)))))
(defn transform-opts [{:keys [method format response-format
params body]
:as opts}]
"Note that if you call GET, POST et al, this function gets
called and will include Transit code in your JS.
If you don't want this to happen, use ajax-request directly
(and use advanced optimisation)."
(let [needs-format (and (nil? body) (not= method "GET"))
rf (if (or format needs-format)
(keyword-request-format format opts))]
(assoc opts
:handler (transform-handler opts)
:format rf
:response-format (keyword-response-format response-format opts))))
(defn easy-ajax-request [uri method opts]
(-> opts
(assoc :uri uri
:method method)
transform-opts
simple/ajax-request))