Skip to content

Commit 7bbde7e

Browse files
committed
wip
1 parent 9b6a969 commit 7bbde7e

File tree

5 files changed

+136
-1
lines changed

5 files changed

+136
-1
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
(ns compojure.api.meta
2+
(:require [compojure.api.common :as common :refer [extract-parameters]]))
3+
4+
(defmulti restructure-param
5+
"Restructures a key value pair in smart routes. By default the key
6+
is consumed form the :parameters map in acc. k = given key, v = value."
7+
(fn [k v acc] k))
8+
9+
(defn restructure [method [path arg & args] {:keys [context?]}]
10+
(let [[options body] (extract-parameters args true)
11+
[path-string lets arg-with-request arg] (destructure-compojure-api-request path arg)
12+
13+
{:keys [lets
14+
letks
15+
responses
16+
middleware
17+
middlewares
18+
swagger
19+
parameters
20+
body]} (reduce
21+
(fn [acc [k v]]
22+
(restructure-param k v (update-in acc [:parameters] dissoc k)))
23+
{:lets lets
24+
:letks []
25+
:responses nil
26+
:middleware []
27+
:swagger {}
28+
:body body}
29+
options)
30+
31+
;; migration helpers
32+
_ (assert (not middlewares) ":middlewares is deprecated with 1.0.0, use :middleware instead.")
33+
_ (assert (not parameters) ":parameters is deprecated with 1.0.0, use :swagger instead.")
34+
35+
;; response coercion middleware, why not just code?
36+
middleware (if (seq responses) (conj middleware `[coerce/body-coercer-middleware (common/merge-vector ~responses)]) middleware)]
37+
38+
(if context?
39+
40+
;; context
41+
(let [form `(compojure.core/routes ~@body)
42+
form (if (seq letks) `(p/letk ~letks ~form) form)
43+
form (if (seq lets) `(let ~lets ~form) form)
44+
form (if (seq middleware) `((mw/compose-middleware ~middleware) ~form) form)
45+
form `(compojure.core/context ~path ~arg-with-request ~form)
46+
47+
;; create and apply a separate lookup-function to find the inner routes
48+
childs (let [form (vec body)
49+
form (if (seq letks) `(dummy-letk ~letks ~form) form)
50+
form (if (seq lets) `(dummy-let ~lets ~form) form)
51+
form `(compojure.core/let-request [~arg-with-request ~'+compojure-api-request+] ~form)
52+
form `(fn [~'+compojure-api-request+] ~form)
53+
form `(~form {})]
54+
form)]
55+
56+
`(routes/create ~path-string ~method (merge-parameters ~swagger) ~childs ~form))
57+
58+
;; endpoints
59+
(let [form `(do ~@body)
60+
form (if (seq letks) `(p/letk ~letks ~form) form)
61+
form (if (seq lets) `(let ~lets ~form) form)
62+
form (compojure.core/compile-route method path arg-with-request (list form))
63+
form (if (seq middleware) `(compojure.core/wrap-routes ~form (mw/compose-middleware ~middleware)) form)]
64+
65+
`(routes/create ~path-string ~method (merge-parameters ~swagger) nil ~form)))))
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
(ns compojure.api.core
2+
(:require [compojure.api.meta :as meta]
3+
[compojure.api.routes :as-alias routes]
4+
[compojure.api.middleware :as-alias mw]))
5+
6+
;; simulate clojure.tools.macro/name-with-attributes
7+
(defn- name-with-attributes [name routes]
8+
(let [routes (cond-> routes
9+
(string? (first routes)) next)
10+
routes (cond-> routes
11+
(map? (first routes)) next)]
12+
[name routes]))
13+
14+
(defmacro defroutes
15+
"Define a Ring handler function from a sequence of routes.
16+
The name may optionally be followed by a doc-string and metadata map."
17+
{:style/indent 1}
18+
[name & routes]
19+
(let [[name routes] (name-with-attributes name routes)]
20+
`(def ~name (routes ~@routes))))
21+
22+
(defmacro let-routes
23+
"Takes a vector of bindings and a body of routes.
24+
25+
Equivalent to: `(let [...] (routes ...))`"
26+
{:style/indent 1}
27+
[bindings & body]
28+
`(let ~bindings (routes ~@body)))
29+
30+
(defmacro middleware
31+
"Wraps routes with given middlewares using thread-first macro.
32+
33+
Note that middlewares will be executed even if routes in body
34+
do not match the request uri. Be careful with middleware that
35+
has side-effects."
36+
{:style/indent 1
37+
:deprecated "1.1.14"
38+
:superseded-by "route-middleware"}
39+
[middleware & body]
40+
`(let [body# (routes ~@body)
41+
wrap-mw# (mw/compose-middleware ~middleware)]
42+
(routes/create nil nil {} [body#] (wrap-mw# body#))))
43+
44+
(defmacro context {:style/indent 2} [& args] (meta/restructure nil args {:context? true :&form &form :&env &env}))
45+
46+
(defmacro GET {:style/indent 2} [& args] (meta/restructure :get args nil))
47+
(defmacro ANY {:style/indent 2} [& args] (meta/restructure nil args nil))
48+
(defmacro HEAD {:style/indent 2} [& args] (meta/restructure :head args nil))
49+
(defmacro PATCH {:style/indent 2} [& args] (meta/restructure :patch args nil))
50+
(defmacro DELETE {:style/indent 2} [& args] (meta/restructure :delete args nil))
51+
(defmacro OPTIONS {:style/indent 2} [& args] (meta/restructure :options args nil))
52+
(defmacro POST {:style/indent 2} [& args] (meta/restructure :post args nil))
53+
(defmacro PUT {:style/indent 2} [& args] (meta/restructure :put args nil))
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{:hooks
2+
{:macroexpand
3+
{compojure.api.core/defroutes compojure.api.core/defroutes}}}

scripts/regen-kondo.clj

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
bb -f ./script/regen_kondo_config.clj
6+
7+
mkdir -p resources/clj-kondo.exports/metosin/compojure-api/compojure/api
8+
9+
;; rename to .clj
10+
cp src/compojure/api/common.cljc resources/clj-kondo.exports/metosin/compojure-api/compojure/api/common.clj

src/compojure/api/common.clj renamed to src/compojure/api/common.cljc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
(ns compojure.api.common
2-
(:require [linked.core :as linked]))
2+
#?@(:bb []
3+
:default [(:require [linked.core :as linked])]))
34

45
(defn plain-map?
56
"checks whether input is a map, but not a record"
@@ -51,6 +52,8 @@
5152
x
5253
y))
5354

55+
#?(:bb nil
56+
:default
5457
(defn fifo-memoize [f size]
5558
"Returns a memoized version of a referentially transparent f. The
5659
memoized version of the function keeps a cache of the mapping from arguments
@@ -66,6 +69,7 @@
6669
(dissoc mem (-> mem first first))
6770
mem))))
6871
value)))))
72+
)
6973

7074
;; NB: when-ns eats all exceptions inside the body, including those about
7175
;; unresolvable symbols. Keep this in mind when debugging the definitions below.

0 commit comments

Comments
 (0)