From 3336880b01f18044fb7068da110857319dc8cc64 Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Wed, 3 May 2023 10:25:01 +0300 Subject: [PATCH] 0.7.0-alpha1 --- CHANGELOG.md | 2 +- README.md | 2 +- doc/README.md | 2 +- doc/basics/error_messages.md | 2 +- doc/http/default_interceptors.md | 2 +- doc/http/interceptors.md | 2 +- doc/http/pedestal.md | 6 +- doc/http/sieppari.md | 2 +- doc/http/transforming_interceptor_chain.md | 2 +- doc/ring/default_middleware.md | 2 +- doc/ring/exceptions.md | 2 +- doc/ring/ring.md | 2 +- doc/ring/swagger.md | 4 +- doc/ring/transforming_middleware_chain.md | 2 +- examples/buddy-auth/project.clj | 2 +- examples/frontend-auth/project.clj | 6 +- examples/frontend-controllers/project.clj | 6 +- examples/frontend-links/project.clj | 6 +- examples/frontend-prompt/project.clj | 6 +- examples/frontend-re-frame/project.clj | 2 +- examples/frontend/project.clj | 6 +- examples/http-swagger/project.clj | 2 +- examples/http/project.clj | 2 +- examples/just-coercion-with-ring/project.clj | 2 +- examples/pedestal-malli-swagger/project.clj | 6 +- examples/pedestal-swagger/project.clj | 4 +- examples/pedestal/project.clj | 4 +- examples/ring-example/project.clj | 2 +- examples/ring-integrant/project.clj | 2 +- examples/ring-malli-lite-swagger/project.clj | 2 +- examples/ring-malli-swagger/project.clj | 2 +- examples/ring-spec-swagger/project.clj | 2 +- examples/ring-swagger/project.clj | 2 +- modules/reitit-core/project.clj | 2 +- modules/reitit-core/src/ctrl/merge.cljc | 189 +++++++++++++++++++ modules/reitit-dev/project.clj | 2 +- modules/reitit-frontend/project.clj | 2 +- modules/reitit-http/project.clj | 2 +- modules/reitit-interceptors/project.clj | 2 +- modules/reitit-malli/project.clj | 2 +- modules/reitit-middleware/project.clj | 2 +- modules/reitit-openapi/project.clj | 2 +- modules/reitit-pedestal/project.clj | 2 +- modules/reitit-ring/project.clj | 2 +- modules/reitit-schema/project.clj | 2 +- modules/reitit-sieppari/project.clj | 2 +- modules/reitit-spec/project.clj | 2 +- modules/reitit-swagger-ui/project.clj | 2 +- modules/reitit-swagger/project.clj | 2 +- modules/reitit/project.clj | 2 +- project.clj | 34 ++-- 51 files changed, 272 insertions(+), 83 deletions(-) create mode 100644 modules/reitit-core/src/ctrl/merge.cljc diff --git a/CHANGELOG.md b/CHANGELOG.md index 193e61c9..1c76aa4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ We use [Break Versioning][breakver]. The version numbers follow a `. obj meta* :displace)) + +(defn- replace? [obj] + (-> obj meta* :replace)) + +(defn- top-displace? [obj] + (-> obj meta* :top-displace)) + +(defn- different-priority? [left right] + (boolean (or (some (some-fn nil? displace? replace?) [left right]) + (top-displace? left)))) + +(defn- remove-top-displace [obj {:keys [::replace-nil]}] + (cond replace-nil nil + (top-displace? obj) obj + :else (vary-meta obj dissoc :top-displace))) + +(defn- pick-prioritized [left right options] + (cond (nil? left) right + (nil? right) (remove-top-displace left options) + + (top-displace? left) right + + (and (displace? left) ;; Pick the rightmost + (displace? right)) ;; if both are marked as displaceable + (with-meta* right + (c/merge (meta* left) (meta* right))) + + (and (replace? left) ;; Pick the rightmost + (replace? right)) ;; if both are marked as replaceable + (with-meta* right + (c/merge (meta* left) (meta* right))) + + (or (displace? left) + (replace? right)) + (with-meta* right + (c/merge (-> left meta* (dissoc :displace)) + (-> right meta* (dissoc :replace)))) + + (or (replace? left) + (displace? right)) + (with-meta* left + (c/merge (-> right meta* (dissoc :displace)) + (-> left meta* (dissoc :replace)))))) + +(defn find-custom-merge [path path-map] + (letfn [(match [x f] (cond (keyword? f) (= x f) (or (fn? f) (ifn? f)) (f x)))] + (reduce (fn [_ [ps f]] (let [match (loop [[p & pr] path, [pp & ppr] ps] + (cond (and p pp (match p pp)) (recur pr ppr) + (= nil p pp) true))] + (when match (reduced f)))) nil path-map))) + +;; +;; public api +;; + +(defn any [_] true) + +(defn merge + ([] {}) + ([left] left) + ([left right] (merge left right nil)) + ([left right {:keys [::path ::path-map] :as options}] + (let [custom-merge (find-custom-merge path path-map)] + (cond + (different-priority? left right) + (pick-prioritized left right options) + + custom-merge + (custom-merge left right options) + + (and (map? left) (map? right)) + (let [merge-entry (fn [m e] + (let [k (key e) v (val e)] + (if (contains? m k) + (assoc m k (merge (get m k) v (update options ::path (fnil conj []) k))) + (assoc m k v)))) + merge2 (fn [m1 m2] + (reduce merge-entry (or m1 {}) (seq m2)))] + (reduce merge2 [left right])) + + (and (set? left) (set? right)) + (set/union right left) + + (and (coll? left) (coll? right)) + (if (or (-> left meta :prepend) + (-> right meta :prepend)) + (-> (into (empty left) (concat right left)) + (with-meta (c/merge (meta left) + (select-keys (meta right) [:displace])))) + (into (empty left) (concat left right))) + + :else right)))) + +;; +;; spike +;; + +(comment + (merge + {:parameters {:query {:x 1}}} + {:parameters {:query nil}} + {::replace-nil true})) + +(ns demo2) + +(require '[reitit.ring :as ring] + '[malli.util :as mu] + '[reitit.core :as r] + '[ctrl.merge :as cm]) + +(defn ring-path-map [f] + [[[:parameters cm/any] f] + [[ring/http-methods :parameters cm/any] f] + [[:responses cm/any :body] f] + [[ring/http-methods :responses cm/any :body] f]]) + +(defn malli-merge [x y _] (mu/merge x y)) + +(-> (ring/router + ["/api" {:parameters {:header [:map ["Api" :string]]}} + ["/math/:x" {:parameters {:path [:map [:x :int]] + :query [:map [:b :string]] + :header [:map ["Math" :string]]} + :responses {200 {:body [:map [:total :int]]} + 500 {:description "fail"}}} + ["/plus/:y" {:get {:parameters {:query ^:replace [:map [:a :int]] + :body [:map [:b :int]] + :header [:map ["Plus" :string]] + :path [:map [:y :int]]} + :responses {200 {:body [:map [:total2 :int]]} + 500 {:description "fail"}} + :handler (constantly {:status 200, :body "ok"})}}]]] + {:meta-merge #(cm/merge %1 %2 {::cm/path-map (ring-path-map malli-merge)})}) + (ring/ring-handler) + (ring/get-router) + (r/compiled-routes) + (last) + (last) + :get + :data) +;{:parameters {:header [:map +; ["Api" :string] +; ["Math" :string] +; ["Plus" :string]], +; :path [:map +; [:x :int] +; [:y :int]], +; :query [:map [:a :int]], +; :body [:map [:b :int]]}, +; :responses {200 {:body [:map +; [:total :int] +; [:total2 :int]]} +; 500 {:description "fail"}}, +; :handler #object[clojure.core$constantly$fn__5740]} + +(cm/merge + {:parameters {:query [:map [:x :int]]} + :get {:parameters {:query [:map [:x :int]]} + :responses {200 {:body [:map [:total :int]]}}}} + {:parameters {:query [:map [:y :int]]} + :get {:parameters {:query [:map [:y :int]]} + :responses {200 {:body [:map [:total :int]]}}} + :post {:parameters {:query [:map [:y :int]]}}} + {::cm/path-map [[[:parameters cm/any] malli-merge] + [[cm/any :parameters cm/any] malli-merge] + [[:responses cm/any :body] malli-merge] + [[cm/any :responses cm/any :body] malli-merge]]}) +;{:parameters {:query [:map [:x :int] [:y :int]]}, +; :get {:parameters {:query [:map [:x :int] [:y :int]]} +; :responses {200 {:body [:map [:total :int]]}}}, +; :post {:parameters {:query [:map [:y :int]]}}} diff --git a/modules/reitit-dev/project.clj b/modules/reitit-dev/project.clj index 1add183f..f5355630 100644 --- a/modules/reitit-dev/project.clj +++ b/modules/reitit-dev/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/reitit-dev "0.6.0" +(defproject metosin/reitit-dev "0.7.0-alpha1" :description "Snappy data-driven router for Clojure(Script)" :url "https://github.com/metosin/reitit" :license {:name "Eclipse Public License" diff --git a/modules/reitit-frontend/project.clj b/modules/reitit-frontend/project.clj index 254a2b67..0b78df79 100644 --- a/modules/reitit-frontend/project.clj +++ b/modules/reitit-frontend/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/reitit-frontend "0.6.0" +(defproject metosin/reitit-frontend "0.7.0-alpha1" :description "Reitit: Clojurescript frontend routing core" :url "https://github.com/metosin/reitit" :license {:name "Eclipse Public License" diff --git a/modules/reitit-http/project.clj b/modules/reitit-http/project.clj index 78ded043..dc667fde 100644 --- a/modules/reitit-http/project.clj +++ b/modules/reitit-http/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/reitit-http "0.6.0" +(defproject metosin/reitit-http "0.7.0-alpha1" :description "Reitit: HTTP routing with interceptors" :url "https://github.com/metosin/reitit" :license {:name "Eclipse Public License" diff --git a/modules/reitit-interceptors/project.clj b/modules/reitit-interceptors/project.clj index cc7224e5..0437dd40 100644 --- a/modules/reitit-interceptors/project.clj +++ b/modules/reitit-interceptors/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/reitit-interceptors "0.6.0" +(defproject metosin/reitit-interceptors "0.7.0-alpha1" :description "Reitit, common interceptors bundled" :url "https://github.com/metosin/reitit" :license {:name "Eclipse Public License" diff --git a/modules/reitit-malli/project.clj b/modules/reitit-malli/project.clj index 044d3bba..0e78e781 100644 --- a/modules/reitit-malli/project.clj +++ b/modules/reitit-malli/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/reitit-malli "0.6.0" +(defproject metosin/reitit-malli "0.7.0-alpha1" :description "Reitit: Malli coercion" :url "https://github.com/metosin/reitit" :license {:name "Eclipse Public License" diff --git a/modules/reitit-middleware/project.clj b/modules/reitit-middleware/project.clj index c81b27f8..5c443430 100644 --- a/modules/reitit-middleware/project.clj +++ b/modules/reitit-middleware/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/reitit-middleware "0.6.0" +(defproject metosin/reitit-middleware "0.7.0-alpha1" :description "Reitit, common middleware bundled" :url "https://github.com/metosin/reitit" :license {:name "Eclipse Public License" diff --git a/modules/reitit-openapi/project.clj b/modules/reitit-openapi/project.clj index 079f8cac..31bc45e9 100644 --- a/modules/reitit-openapi/project.clj +++ b/modules/reitit-openapi/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/reitit-openapi "0.6.0" +(defproject metosin/reitit-openapi "0.7.0-alpha1" :description "Reitit: OpenAPI-support" :url "https://github.com/metosin/reitit" :license {:name "Eclipse Public License" diff --git a/modules/reitit-pedestal/project.clj b/modules/reitit-pedestal/project.clj index 5e7ed9a3..9d49f1a7 100644 --- a/modules/reitit-pedestal/project.clj +++ b/modules/reitit-pedestal/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/reitit-pedestal "0.6.0" +(defproject metosin/reitit-pedestal "0.7.0-alpha1" :description "Reitit + Pedestal Integration" :url "https://github.com/metosin/reitit" :license {:name "Eclipse Public License" diff --git a/modules/reitit-ring/project.clj b/modules/reitit-ring/project.clj index 2b6b8053..4d6e79d9 100644 --- a/modules/reitit-ring/project.clj +++ b/modules/reitit-ring/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/reitit-ring "0.6.0" +(defproject metosin/reitit-ring "0.7.0-alpha1" :description "Reitit: Ring routing" :url "https://github.com/metosin/reitit" :license {:name "Eclipse Public License" diff --git a/modules/reitit-schema/project.clj b/modules/reitit-schema/project.clj index e5e44be5..6c9e0eeb 100644 --- a/modules/reitit-schema/project.clj +++ b/modules/reitit-schema/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/reitit-schema "0.6.0" +(defproject metosin/reitit-schema "0.7.0-alpha1" :description "Reitit: Plumatic Schema coercion" :url "https://github.com/metosin/reitit" :license {:name "Eclipse Public License" diff --git a/modules/reitit-sieppari/project.clj b/modules/reitit-sieppari/project.clj index ba69d102..3b1898a7 100644 --- a/modules/reitit-sieppari/project.clj +++ b/modules/reitit-sieppari/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/reitit-sieppari "0.6.0" +(defproject metosin/reitit-sieppari "0.7.0-alpha1" :description "Reitit: Sieppari Interceptors" :url "https://github.com/metosin/reitit" :license {:name "Eclipse Public License" diff --git a/modules/reitit-spec/project.clj b/modules/reitit-spec/project.clj index b9cf5f84..cd237b72 100644 --- a/modules/reitit-spec/project.clj +++ b/modules/reitit-spec/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/reitit-spec "0.6.0" +(defproject metosin/reitit-spec "0.7.0-alpha1" :description "Reitit: clojure.spec coercion" :url "https://github.com/metosin/reitit" :license {:name "Eclipse Public License" diff --git a/modules/reitit-swagger-ui/project.clj b/modules/reitit-swagger-ui/project.clj index 318076a3..0993a586 100644 --- a/modules/reitit-swagger-ui/project.clj +++ b/modules/reitit-swagger-ui/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/reitit-swagger-ui "0.6.0" +(defproject metosin/reitit-swagger-ui "0.7.0-alpha1" :description "Reitit: Swagger-ui support" :url "https://github.com/metosin/reitit" :license {:name "Eclipse Public License" diff --git a/modules/reitit-swagger/project.clj b/modules/reitit-swagger/project.clj index a52ca20d..130bcb85 100644 --- a/modules/reitit-swagger/project.clj +++ b/modules/reitit-swagger/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/reitit-swagger "0.6.0" +(defproject metosin/reitit-swagger "0.7.0-alpha1" :description "Reitit: Swagger-support" :url "https://github.com/metosin/reitit" :license {:name "Eclipse Public License" diff --git a/modules/reitit/project.clj b/modules/reitit/project.clj index 14be2f42..196d2260 100644 --- a/modules/reitit/project.clj +++ b/modules/reitit/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/reitit "0.6.0" +(defproject metosin/reitit "0.7.0-alpha1" :description "Snappy data-driven router for Clojure(Script)" :url "https://github.com/metosin/reitit" :license {:name "Eclipse Public License" diff --git a/project.clj b/project.clj index 801a7706..5911c729 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/reitit-parent "0.6.0" +(defproject metosin/reitit-parent "0.7.0-alpha1" :description "Snappy data-driven router for Clojure(Script)" :url "https://github.com/metosin/reitit" :license {:name "Eclipse Public License" @@ -15,22 +15,22 @@ :url "https://github.com/metosin/reitit"} ;; TODO: need to verify that the code actually worked with Java1.8, see #242 :javac-options ["-Xlint:unchecked" "-target" "1.8" "-source" "1.8"] - :managed-dependencies [[metosin/reitit "0.6.0"] - [metosin/reitit-core "0.6.0"] - [metosin/reitit-dev "0.6.0"] - [metosin/reitit-spec "0.6.0"] - [metosin/reitit-malli "0.6.0"] - [metosin/reitit-schema "0.6.0"] - [metosin/reitit-ring "0.6.0"] - [metosin/reitit-middleware "0.6.0"] - [metosin/reitit-http "0.6.0"] - [metosin/reitit-interceptors "0.6.0"] - [metosin/reitit-swagger "0.6.0"] - [metosin/reitit-openapi "0.6.0"] - [metosin/reitit-swagger-ui "0.6.0"] - [metosin/reitit-frontend "0.6.0"] - [metosin/reitit-sieppari "0.6.0"] - [metosin/reitit-pedestal "0.6.0"] + :managed-dependencies [[metosin/reitit "0.7.0-alpha1"] + [metosin/reitit-core "0.7.0-alpha1"] + [metosin/reitit-dev "0.7.0-alpha1"] + [metosin/reitit-spec "0.7.0-alpha1"] + [metosin/reitit-malli "0.7.0-alpha1"] + [metosin/reitit-schema "0.7.0-alpha1"] + [metosin/reitit-ring "0.7.0-alpha1"] + [metosin/reitit-middleware "0.7.0-alpha1"] + [metosin/reitit-http "0.7.0-alpha1"] + [metosin/reitit-interceptors "0.7.0-alpha1"] + [metosin/reitit-swagger "0.7.0-alpha1"] + [metosin/reitit-openapi "0.7.0-alpha1"] + [metosin/reitit-swagger-ui "0.7.0-alpha1"] + [metosin/reitit-frontend "0.7.0-alpha1"] + [metosin/reitit-sieppari "0.7.0-alpha1"] + [metosin/reitit-pedestal "0.7.0-alpha1"] [metosin/ring-swagger-ui "4.18.1"] [metosin/spec-tools "0.10.5"] [metosin/schema-tools "0.13.0"]