diff --git a/CHANGELOG.md b/CHANGELOG.md index a3c85d02..e1f8084b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ We use [Break Versioning][breakver]. The version numbers follow a `.> (for [[in schema] parameters - parameter (extract-parameter in schema options)] - parameter) - (into []))}) - (if responses - {:responses - (into - (empty responses) - (for [[status response] responses] - [status (as-> response $ - (set/rename-keys $ {:body :schema}) - (update $ :description (fnil identity "")) - (if (:schema $) - (update $ :schema swagger/transform {:type :schema}) - $))]))})) + :swagger (swagger/swagger-spec + (merge + (if parameters + {::swagger/parameters + (into + (empty parameters) + (for [[k v] parameters] + [k (compile v options)]))}) + (if responses + {::swagger/responses + (into + (empty responses) + (for [[k response] responses] + [k (as-> response $ + (set/rename-keys $ {:body :schema}) + (if (:schema $) + (update $ :schema compile options) + $))]))}))) ;; :openapi handled in reitit.openapi/-get-apidocs-openapi (throw (ex-info diff --git a/modules/reitit-schema/src/reitit/coercion/schema.cljc b/modules/reitit-schema/src/reitit/coercion/schema.cljc index edd5f72e..b2fd14d1 100644 --- a/modules/reitit-schema/src/reitit/coercion/schema.cljc +++ b/modules/reitit-schema/src/reitit/coercion/schema.cljc @@ -67,7 +67,9 @@ (into (empty responses) (for [[k response] responses] - [k (set/rename-keys response {:body :schema})]))}))) + [k (-> response + (dissoc :content) + (set/rename-keys {:body :schema}))]))}))) ;; :openapi handled in reitit.openapi/-get-apidocs-openapi (throw (ex-info diff --git a/modules/reitit-spec/src/reitit/coercion/spec.cljc b/modules/reitit-spec/src/reitit/coercion/spec.cljc index ba251675..bf4bed82 100644 --- a/modules/reitit-spec/src/reitit/coercion/spec.cljc +++ b/modules/reitit-spec/src/reitit/coercion/spec.cljc @@ -108,6 +108,7 @@ (empty responses) (for [[k response] responses] [k (as-> response $ + (dissoc $ :content) (set/rename-keys $ {:body :schema}))]))}))) ;; :openapi handled in reitit.openapi/-get-apidocs-openapi (throw diff --git a/modules/reitit-swagger/src/reitit/swagger.cljc b/modules/reitit-swagger/src/reitit/swagger.cljc index 26c9073d..50c1ceb4 100644 --- a/modules/reitit-swagger/src/reitit/swagger.cljc +++ b/modules/reitit-swagger/src/reitit/swagger.cljc @@ -10,7 +10,6 @@ (s/def ::id (s/or :keyword keyword? :set (s/coll-of keyword? :into #{}))) (s/def ::no-doc boolean?) (s/def ::tags (s/coll-of (s/or :keyword keyword? :string string?) :kind set?)) -(s/def ::operationId string?) (s/def ::summary string?) (s/def ::description string?) (s/def ::operationId string?) @@ -126,9 +125,15 @@ (if-let [endpoint (some->> c (keep transform-endpoint) (seq) (into {}))] [(swagger-path p (r/options router)) endpoint])) map-in-order #(->> % (apply concat) (apply array-map)) - paths (->> router (r/compiled-routes) (filter accept-route) (map transform-path) map-in-order)] + paths (->> router (r/compiled-routes) (filter accept-route) (map transform-path) map-in-order) + definitions (apply merge + (for [[_path path-data] paths + [_method data] path-data] + (:definitions data))) + paths-without-definitions (update-vals paths (fn [methods] + (update-vals methods #(dissoc % :definitions))))] {:status 200 - :body (meta-merge swagger {:paths paths})})) + :body (meta-merge swagger {:paths paths-without-definitions :definitions definitions})})) ([req res raise] (try (res (create-swagger req)) diff --git a/project.clj b/project.clj index 4387218e..ca3ae3cc 100644 --- a/project.clj +++ b/project.clj @@ -37,7 +37,7 @@ [metosin/muuntaja "0.6.8"] [metosin/jsonista "0.3.7"] [metosin/sieppari "0.0.0-alpha13"] - [metosin/malli "0.11.0"] + [metosin/malli "0.12.0"] ;; https://clojureverse.org/t/depending-on-the-right-versions-of-jackson-libraries/5111 [com.fasterxml.jackson.core/jackson-core "2.15.1"] @@ -95,7 +95,7 @@ [metosin/muuntaja "0.6.8"] [metosin/sieppari "0.0.0-alpha13"] [metosin/jsonista "0.3.7"] - [metosin/malli "0.11.0"] + [metosin/malli "0.12.0"] [lambdaisland/deep-diff "0.0-47"] [meta-merge "1.0.0"] [com.bhauman/spell-spec "0.1.2"] @@ -126,7 +126,6 @@ [ring-cors "0.1.13"] [com.bhauman/rebel-readline "0.1.4"]]} - :1.10 {:dependencies [[org.clojure/clojure "1.10.3"]]} :perf {:jvm-opts ^:replace ["-server" "-Xmx4096m" "-Dclojure.compiler.direct-linking=true"] @@ -152,7 +151,7 @@ "-XX:+PrintCompilation" "-XX:+UnlockDiagnosticVMOptions" "-XX:+PrintInlining"]}} - :aliases {"all" ["with-profile" "dev,default:dev,default,1.10"] + :aliases {"all" ["with-profile" "dev,default"] "perf" ["with-profile" "default,dev,perf"] "test-clj" ["all" "do" ["bat-test"] ["check"]] "test-browser" ["doo" "chrome-headless" "test"] diff --git a/scripts/cljdoc-check.sh b/scripts/cljdoc-check.sh index a8b4e005..da7a599b 100755 --- a/scripts/cljdoc-check.sh +++ b/scripts/cljdoc-check.sh @@ -9,6 +9,10 @@ set -e for i in modules/*; do cd $i - clojure -J-Dclojure.main.report=stderr -Tcljdoc-analyzer analyze-local + if [ "$(ls -A src)" ]; then + clojure -J-Dclojure.main.report=stderr -Tcljdoc-analyzer analyze-local + else + echo "Skip $i, empty src folder" + fi cd ../.. done diff --git a/test/cljc/reitit/swagger_test.clj b/test/cljc/reitit/swagger_test.clj index 2862edf1..40902704 100644 --- a/test/cljc/reitit/swagger_test.clj +++ b/test/cljc/reitit/swagger_test.clj @@ -12,7 +12,8 @@ [reitit.swagger :as swagger] [reitit.swagger-ui :as swagger-ui] [schema.core :as s] - [spec-tools.data-spec :as ds])) + [spec-tools.data-spec :as ds] + [malli.core :as mc])) (defn- normalize "Normalize format of swagger spec by converting it to json and back. @@ -22,6 +23,23 @@ j/write-value-as-string (j/read-value j/keyword-keys-object-mapper))) +(def malli-registry + (merge + (mc/base-schemas) + (mc/predicate-schemas) + (mc/type-schemas) + {::req-key [:or :keyword :string] + ::req-val [:or map? :string] + ::resp-map map? + ::resp-string [:string {:min 1}]})) + + +(def PutReqBody + (mc/schema [:map-of ::req-key ::req-val] {:registry malli-registry})) + +(def PutRespBody + (mc/schema [:or ::resp-map ::resp-string] {:registry malli-registry})) + (def app (ring/ring-handler (ring/router @@ -84,7 +102,13 @@ 500 {:description "fail"}} :handler (fn [{{{:keys [z]} :path xs :body} :parameters}] - {:status 200, :body {:total (+ (reduce + xs) z)}})}}]] + {:status 200, :body {:total (+ (reduce + xs) z)}})} + :put {:summary "plus put with definitions" + :parameters {:body PutReqBody} + :responses {200 {:body PutRespBody} + 500 {:description "fail"}} + :handler (fn [{{body :body} :parameters}] + {:status 200, :body (str "got " body)})}}]] ["/schema" {:coercion schema/coercion} ["/plus/*z" @@ -137,6 +161,15 @@ expected {:x-id #{::math} :swagger "2.0" :info {:title "my-api"} + :definitions {::req-key {:type "string" + :x-anyOf [{:type "string"} + {:type "string"}]} + ::req-val {:type "object" + :x-anyOf [{:type "object"} + {:type "string"}]} + ::resp-map {:type "object"}, + ::resp-string {:type "string" + :minLength 1}} :paths {"/api/spec/plus/{z}" {:patch {:parameters [] :summary "patch" :operationId "Patch" @@ -246,7 +279,23 @@ 400 {:schema {:type "string"} :description "kosh"} 500 {:description "fail"}} - :summary "plus with body"}} + :summary "plus with body"} + :put {:parameters [{:in "body" + :name "body" + :description "" + :required true + :schema + {:type "object" + :additionalProperties + {:$ref "#/definitions/reitit.swagger-test~1req-val"}}}] + :responses {200 + {:schema + {:$ref "#/definitions/reitit.swagger-test~1resp-map" + :x-anyOf [{:$ref "#/definitions/reitit.swagger-test~1resp-map"} + {:$ref "#/definitions/reitit.swagger-test~1resp-string"}]} + :description ""} + 500 {:description "fail"}} + :summary "plus put with definitions"}} "/api/schema/plus/{z}" {:get {:parameters [{:description "" :format "int32" :in "query"