Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
frenchy64 committed Aug 30, 2024
1 parent 2658085 commit 34670f2
Show file tree
Hide file tree
Showing 4 changed files with 475 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -1,20 +1,50 @@
(ns compojure.api.meta
(:require [compojure.api.common :as common :refer [extract-parameters]]
[compojure.api.middleware :as-alias mw]
[compojure.api.routes :as-alias routes]
[plumbing.core :as-alias p]
[plumbing.fnk.impl :as-alias fnk-impl]
[ring.swagger.common :as-alias rsc]
;[ring.swagger.json-schema :as js]
[schema.core :as-alias s]
[schema-tools.core :as-alias st]
[compojure.api.coerce :as-alias coerce]
[compojure.api.middleware :as mw]
[compojure.api.routes :as routes]
[plumbing.core :as p]
[plumbing.fnk.impl :as fnk-impl]
[ring.swagger.common :as rsc]
[ring.swagger.json-schema :as js]
[schema.core :as s]
[schema-tools.core :as st]
[compojure.api.coerce :as coerce]
compojure.core))

(def +compojure-api-request+
"lexically bound ring-request for handlers."
'+compojure-api-request+)

;; https://github.com/clojure/tools.macro/blob/415512648bb51153f380823c41323cda2c13f47f/src/main/clojure/clojure/tools/macro.clj
;; Copyright (c) Rich Hickey. All rights reserved.
;; The use and distribution terms for this software are covered by the Eclipse Public License 1.0 (https://opensource.org/license/epl-1-0/)
;; which can be found in the file epl-v10.html at the root of this distribution. By using this software in any fashion, you are agreeing to
;; be bound bythe terms of this license. You must not remove this notice, or any other, from this software.
(defn name-with-attributes
"To be used in macro definitions.
Handles optional docstrings and attribute maps for a name to be defined
in a list of macro arguments. If the first macro argument is a string,
it is added as a docstring to name and removed from the macro argument
list. If afterwards the first macro argument is a map, its entries are
added to the name's metadata map and the map is removed from the
macro argument list. The return value is a vector containing the name
with its extended metadata map and the list of unprocessed macro
arguments."
[name macro-args]
(let [[docstring macro-args] (if (string? (first macro-args))
[(first macro-args) (next macro-args)]
[nil macro-args])
[attr macro-args] (if (map? (first macro-args))
[(first macro-args) (next macro-args)]
[{} macro-args])
attr (if docstring
(assoc attr :doc docstring)
attr)
attr (if (meta name)
(conj (meta name) attr)
attr)]
[(with-meta name attr) macro-args]))

;;
;; Schema
;;
Expand All @@ -39,8 +69,7 @@

(defn- convert-return [schema]
{200 {:schema schema
;:description (or (js/json-schema-meta schema) "")
}})
:description (or (js/json-schema-meta schema) "")}})

;;
;; Extension point
Expand Down Expand Up @@ -226,6 +255,38 @@
(defmethod restructure-param :coercion [_ coercion acc]
(update-in acc [:middleware] conj [mw/wrap-coercion coercion]))

;;
;; Impl
;;

(defmacro dummy-let
"Dummy let-macro used in resolving route-docs. not part of normal invocation chain."
[bindings & body]
(let [bind-form (vec (apply concat (for [n (take-nth 2 bindings)] [n nil])))]
`(let ~bind-form ~@body)))

(defmacro dummy-letk
"Dummy letk-macro used in resolving route-docs. not part of normal invocation chain."
[bindings & body]
(reduce
(fn [cur-body-form [bind-form]]
(if (symbol? bind-form)
`(let [~bind-form nil] ~cur-body-form)
(let [{:keys [map-sym body-form]} (fnk-impl/letk-input-schema-and-body-form
&env
(fnk-impl/ensure-schema-metadata &env bind-form)
[]
cur-body-form)
body-form (clojure.walk/prewalk-replace {'plumbing.fnk.schema/safe-get 'clojure.core/get} body-form)]
`(let [~map-sym nil] ~body-form))))
`(do ~@body)
(reverse (partition 2 bindings))))

(defn routing [handlers]
(if-let [handlers (seq (keep identity (flatten handlers)))]
(apply compojure.core/routes handlers)
(fn ([_] nil) ([_ respond _] (respond nil)))))

;;
;; Api
;;
Expand All @@ -252,14 +313,15 @@
(str "unknown compojure destruction syntax: " arg))))))

(defn merge-parameters
"Merge parameters at runtime to allow usage of runtime-paramers with route-macros."
"Merge parameters at runtime to allow usage of runtime-parameters with route-macros."
[{:keys [responses swagger] :as parameters}]
(cond-> parameters
;(seq responses) (assoc :responses (common/merge-vector responses))
;swagger (-> (dissoc :swagger) (rsc/deep-merge swagger))
))
(seq responses) (assoc :responses (common/merge-vector responses))
swagger (-> (dissoc :swagger) (rsc/deep-merge swagger))))

(defn restructure [method [path arg & args] {:keys [context?]}]
(defn restructure [method [path arg & args] {:keys [context? kondo-rule?]}]
#?(:bb (assert kondo-rule?)
:default nil)
(let [[options body] (extract-parameters args true)
[path-string lets arg-with-request arg] (destructure-compojure-api-request path arg)

Expand All @@ -278,7 +340,8 @@
:responses nil
:middleware []
:swagger {}
:body body}
:body body
:kondo-rule? kondo-rule?}
options)

;; migration helpers
Expand All @@ -295,9 +358,18 @@
form (if (seq letks) `(p/letk ~letks ~form) form)
form (if (seq lets) `(let ~lets ~form) form)
form (if (seq middleware) `((mw/compose-middleware ~middleware) ~form) form)
form `(compojure.core/context ~path ~arg-with-request ~form)]

`(routes/create ~path-string ~method (merge-parameters ~swagger) nil ~form))
form `(compojure.core/context ~path ~arg-with-request ~form)

;; create and apply a separate lookup-function to find the inner routes
childs (let [form (vec body)
form (if (seq letks) `(dummy-letk ~letks ~form) form)
form (if (seq lets) `(dummy-let ~lets ~form) form)
form `(compojure.core/let-request [~arg-with-request ~'+compojure-api-request+] ~form)
form `(fn [~'+compojure-api-request+] ~form)
form `(~form {})]
form)]

`(routes/create ~path-string ~method (merge-parameters ~swagger) ~childs ~form))

;; endpoints
(let [form `(do ~@body)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1 @@
{:hooks
{:macroexpand
{compojure.api.sweet/GET compojure.api.core/GET
compojure.api.core/GET compojure.api.core/GET
compojure.api.core/defroutes compojure.api.core/defroutes}}}
{:hooks {:macroexpand {compojure.api.core/GET compojure.api.core/GET}}}
Loading

0 comments on commit 34670f2

Please sign in to comment.