/
client.clj
102 lines (91 loc) · 2.99 KB
/
client.clj
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
(ns relative-clj-http.client
(:require [clj-http.client :as http-client]
[clojure.string :as str])
(:import (java.net URI)))
; TODO: this does not proplery deal with more .. than there is path
(defn- normalize-url
"Normalize the URL to it's most direct and absolute form. E.g. resolve `..`."
[url]
(-> (URI/create url)
(.normalize)
(.toString)
; `..` in normalize remain on first level
(str/replace #"\.\./?" "")))
(defn- absolute-url?
"Predicate, if the URL is considered absolute"
[url]
(boolean (some? (re-find #"://" url))))
(def ^:const default-config
"Starting config"
{:base-url "http://localhost:8080"
:request {:as :auto
:coerce :always
:throw-exceptions false
:debug false}})
(defn set-default
"Convenience method to set a request default in the config"
[config & args]
(assoc-in config (into [:request] (drop-last args)) (last args)))
(defn home
"The starting, or base URL, of the config"
[config]
(get config :base-url))
(defn pwd
"The current url in the config"
[config]
(get config :current-url (:base-url config)))
(defn old-pwd
"The previous url in the config"
[config]
(get config :previous-url (:current-url config)))
(defn- remember-old-pwd
"Helper to change the current url and remember the previous one"
[config new-pwd]
(let [old-pwd (pwd config)]
(assoc config
:current-url new-pwd
:previous-url old-pwd)))
(defn cd
"Change directory in the config.
- with no param given, jump back to the current base
- given a path, change relative or absolute URL
- a single `-` will change back to the previous URL
- a leading `~` changes relative to the current base
- with two params replace any occurence of the first argument in the pwd with the second"
([config]
(cd config (home config)))
([config path]
(cond
; absolute url changes base too and sets current
(absolute-url? path)
(remember-old-pwd
(assoc config :base-url path)
path)
; a `-` changes back to the previous url
(= path "-")
(remember-old-pwd
config
(old-pwd config))
; "regular" case
:else
(remember-old-pwd
config
(normalize-url (cond
(str/starts-with? path "~") (str (home config) "/" (subs path 1))
:else (str (pwd config) "/" path))))))
([config old new]
(remember-old-pwd config (str/replace (pwd config) old new))))
(defn request
"Same as clj-http.client/request, but using the passed in config for URL transformation"
([config method]
(request config method (pwd config) {}))
([config method path]
(request config method path {}))
([config method path request]
(let [default-request (get config :request {})
crequest (merge
default-request
request
{:method method
:url (-> config (cd path) (pwd))})]
(http-client/request crequest))))