diff --git a/src/ring/openapi/openapi3.clj b/src/ring/openapi/openapi3.clj index 1b863f2..b591075 100644 --- a/src/ring/openapi/openapi3.clj +++ b/src/ring/openapi/openapi3.clj @@ -39,7 +39,7 @@ (for [[k v] (-> model common/value-of stc/schema-value rsc/strict-schema) :when (s/specific-key? k) :let [rk (s/explicit-schema-key k) - json-schema (rsjs/->swagger v options :openapi)] + json-schema (rsjs/->swagger v (assoc options :schema-type :openapi))] :when json-schema] {:in (name in) :name (rsjs/key-name rk) @@ -60,7 +60,7 @@ (into {} (for [[content-type schema-input] contents] [content-type (let [schema (rsc/peek-schema schema-input) - schema-json (rsjs/->swagger schema-input options :openapi)] + schema-json (rsjs/->swagger schema-input (assoc options :schema-type :openapi))] {:name (or (common/title schema) "") :schema schema-json})])))) @@ -78,7 +78,7 @@ (cond-> headers (update-in [:headers] (fn [headers] (if headers (->> (for [[k v] headers] - [k (rsjs/->swagger v options :openapi)]) + [k (rsjs/->swagger v (assoc options :schema-type :openapi))]) (into {})))))) (update-in [:description] #(or % (:description (rsjs/json-schema-meta v)) diff --git a/src/ring/swagger/json_schema.clj b/src/ring/swagger/json_schema.clj index 44bcc5f..ad1a5a3 100644 --- a/src/ring/swagger/json_schema.clj +++ b/src/ring/swagger/json_schema.clj @@ -56,10 +56,10 @@ (str (if n (str n "/")) (name x))) x)) -(defmulti convert-class (fn [c _ _] c)) +(defmulti convert-class (fn [c _] c)) (defprotocol JsonSchema - (convert [this options schema-type])) + (convert [this options])) (defn not-supported! [e] (throw (IllegalArgumentException. @@ -92,28 +92,28 @@ m)) ;; Classes -(defmethod convert-class java.lang.Integer [_ _ _] {:type "integer" :format "int32"}) -(defmethod convert-class java.lang.Long [_ _ _] {:type "integer" :format "int64"}) -(defmethod convert-class java.lang.Double [_ _ _] {:type "number" :format "double"}) -(defmethod convert-class java.lang.Number [_ _ _] {:type "number" :format "double"}) -(defmethod convert-class java.lang.String [_ _ _] {:type "string"}) -(defmethod convert-class java.lang.Boolean [_ _ _] {:type "boolean"}) -(defmethod convert-class clojure.lang.Keyword [_ _ _] {:type "string"}) -(defmethod convert-class clojure.lang.Symbol [_ _ _] {:type "string"}) -(defmethod convert-class java.util.UUID [_ _ _] {:type "string" :format "uuid"}) -(defmethod convert-class java.util.Date [_ _ _] {:type "string" :format "date-time"}) -(defmethod convert-class org.joda.time.DateTime [_ _ _] {:type "string" :format "date-time"}) -(defmethod convert-class org.joda.time.LocalDate [_ _ _] {:type "string" :format "date"}) -(defmethod convert-class org.joda.time.LocalTime [_ _ _] {:type "string" :format "time"}) -(defmethod convert-class java.util.regex.Pattern [_ _ _] {:type "string" :format "regex"}) -(defmethod convert-class java.io.File [_ _ _] {:type "file"}) +(defmethod convert-class java.lang.Integer [_ _] {:type "integer" :format "int32"}) +(defmethod convert-class java.lang.Long [_ _] {:type "integer" :format "int64"}) +(defmethod convert-class java.lang.Double [_ _] {:type "number" :format "double"}) +(defmethod convert-class java.lang.Number [_ _] {:type "number" :format "double"}) +(defmethod convert-class java.lang.String [_ _] {:type "string"}) +(defmethod convert-class java.lang.Boolean [_ _] {:type "boolean"}) +(defmethod convert-class clojure.lang.Keyword [_ _] {:type "string"}) +(defmethod convert-class clojure.lang.Symbol [_ _] {:type "string"}) +(defmethod convert-class java.util.UUID [_ _] {:type "string" :format "uuid"}) +(defmethod convert-class java.util.Date [_ _] {:type "string" :format "date-time"}) +(defmethod convert-class org.joda.time.DateTime [_ _] {:type "string" :format "date-time"}) +(defmethod convert-class org.joda.time.LocalDate [_ _] {:type "string" :format "date"}) +(defmethod convert-class org.joda.time.LocalTime [_ _] {:type "string" :format "time"}) +(defmethod convert-class java.util.regex.Pattern [_ _] {:type "string" :format "regex"}) +(defmethod convert-class java.io.File [_ _] {:type "file"}) (extension/java-time - (defmethod convert-class java.time.Instant [_ _ _] {:type "string" :format "date-time"}) - (defmethod convert-class java.time.LocalDate [_ _ _] {:type "string" :format "date"}) - (defmethod convert-class java.time.LocalTime [_ _ _] {:type "string" :format "time"})) + (defmethod convert-class java.time.Instant [_ _] {:type "string" :format "date-time"}) + (defmethod convert-class java.time.LocalDate [_ _] {:type "string" :format "date"}) + (defmethod convert-class java.time.LocalTime [_ _] {:type "string" :format "time"})) -(defmethod convert-class :default [e _ _] +(defmethod convert-class :default [e _] (if-not *ignore-missing-mappings* (not-supported! e))) @@ -127,56 +127,55 @@ (defn ->swagger ([x] - (->swagger x {} :swagger)) - ([x options schema-type] + (->swagger x {})) + ([x options] (-> x - (convert options schema-type) + (convert options) (merge-meta x options)))) (defn try->swagger [v k key-meta schema-type] - (try (->swagger v {:key-meta key-meta} schema-type) + (try (->swagger v {:key-meta key-meta :schema-type schema-type}) (catch Exception e (throw (IllegalArgumentException. (str "error converting to swagger schema [" k " " (try (s/explain v) (catch Exception _ v)) "]") e))))) - -(defn- coll-schema [e options schema-type] +(defn- coll-schema [e options] (-> {:type "array" - :items (->swagger (first e) (assoc options ::no-meta true) schema-type)} + :items (->swagger (first e) (assoc options ::no-meta true))} (assoc-collection-format options))) (extend-protocol JsonSchema Object - (convert [e _ _] + (convert [e _] (not-supported! e)) Class - (convert [e options schema-type] + (convert [e options] (if-let [schema (common/record-schema e)] - (schema-object schema schema-type) - (convert-class e options schema-type))) + (schema-object schema (:schema-type options)) + (convert-class e options))) nil - (convert [_ _ _] + (convert [_ _] nil) FieldSchema - (convert [e _ schema-type] - (->swagger (:schema e) {} schema-type)) + (convert [e _] + (->swagger (:schema e) {})) schema.core.Predicate - (convert [e _ schema-type] - (some-> e :pred-name predicate-name-to-class (->swagger {} schema-type))) + (convert [e _] + (some-> e :pred-name predicate-name-to-class (->swagger {}))) schema.core.EnumSchema - (convert [e options schema-type] - (merge (->swagger (class (first (:vs e))) options schema-type) {:enum (seq (:vs e))})) + (convert [e options] + (merge (->swagger (class (first (:vs e))) options) {:enum (seq (:vs e))})) schema.core.Maybe - (convert [e {:keys [in]} _] + (convert [e {:keys [in]}] (let [schema (->swagger (:schema e))] (condp contains? in #{:query :formData} (assoc schema :allowEmptyValue true) @@ -184,70 +183,70 @@ schema))) schema.core.Both - (convert [e _ _] + (convert [e _] (->swagger (first (:schemas e)))) schema.core.Either - (convert [e _ _] + (convert [e _] (->swagger (first (:schemas e)))) schema.core.Recursive - (convert [e _ _] + (convert [e _] (->swagger (:derefable e))) schema.core.EqSchema - (convert [e _ _] + (convert [e _] (merge (->swagger (class (:v e))) {:enum [(:v e)]})) schema.core.NamedSchema - (convert [e _ schema-type] - (->swagger (:schema e) {} schema-type)) + (convert [e _] + (->swagger (:schema e) {})) schema.core.One - (convert [e _ _] + (convert [e _] (->swagger (:schema e))) schema.core.AnythingSchema - (convert [_ {:keys [in] :as opts} schema-type] + (convert [_ {:keys [in] :as opts}] (if (and in (not= :body in)) - (->swagger (s/maybe s/Str) opts schema-type) + (->swagger (s/maybe s/Str) opts) {})) schema.core.ConditionalSchema - (convert [e _ _] + (convert [e _] {:x-oneOf (vec (keep (comp ->swagger second) (:preds-and-schemas e)))}) schema.core.CondPre - (convert [e _ _] + (convert [e _] {:x-oneOf (mapv ->swagger (:schemas e))}) schema.core.Constrained - (convert [e _ _] + (convert [e _] (->swagger (:schema e))) java.util.regex.Pattern - (convert [e _ _] + (convert [e _] {:type "string" :pattern (str e)}) ;; Collections clojure.lang.Sequential - (convert [e options schema-type] - (coll-schema e options schema-type)) + (convert [e options] + (coll-schema e options)) clojure.lang.IPersistentSet - (convert [e options schema-type] - (assoc (coll-schema e options schema-type) :uniqueItems true)) + (convert [e options] + (assoc (coll-schema e options) :uniqueItems true)) clojure.lang.IPersistentMap - (convert [e {:keys [properties?]} schema-type] + (convert [e {:keys [properties? schema-type]}] (if properties? {:properties (properties e schema-type)} (reference e schema-type))) clojure.lang.Var - (convert [e _ schema-type] + (convert [e {:keys [schema-type]}] (reference e schema-type))) ;; diff --git a/src/ring/swagger/json_schema_dirty.clj b/src/ring/swagger/json_schema_dirty.clj index 04b3f52..8f0ea2c 100644 --- a/src/ring/swagger/json_schema_dirty.clj +++ b/src/ring/swagger/json_schema_dirty.clj @@ -6,18 +6,18 @@ (extend-protocol json-schema/JsonSchema schema.experimental.abstract_map.AbstractSchema - (convert [e {:keys [properties?] - :or {properties? true}} schema-type] + (convert [e {:keys [properties? schema-type] + :or {properties? true}} ] (if properties? (merge {:discriminator (name (:dispatch-key e))} - (json-schema/->swagger (:schema e) {:properties? properties?} schema-type)) + (json-schema/->swagger (:schema e) {:properties? properties? :schema-type schema-type})) (json-schema/reference e schema-type))) schema.experimental.abstract_map.SchemaExtension - (convert [e options schema-type] - {:allOf [(json-schema/->swagger (:base-schema e) {:properties? false} schema-type) + (convert [e {:keys [schema-type] :as options}] + {:allOf [(json-schema/->swagger (:base-schema e) {:properties? false :schema-type schema-type}) ; Find which keys are also in base-schema and don't include them in these properties (json-schema/->swagger (let [base-keys (set (keys (:schema (:base-schema e)))) - m (:extended-schema e)] + m (:extended-schema e)] (into (empty m) (remove (comp base-keys key) m))) - {:properties? true} schema-type)]})) + {:properties? true :schema-type schema-type})]})) diff --git a/src/ring/swagger/swagger2.clj b/src/ring/swagger/swagger2.clj index 4be8f19..913ec82 100644 --- a/src/ring/swagger/swagger2.clj +++ b/src/ring/swagger/swagger2.clj @@ -37,12 +37,12 @@ ;; Paths, parameters, responses ;; -(defmulti extract-parameter (fn [in _ _] in)) +(defmulti ^:private extract-parameter (fn [in _ _] in)) (defmethod extract-parameter :body [_ model options] (if model (let [schema (rsc/peek-schema model) - schema-json (rsjs/->swagger model options :swagger)] + schema-json (rsjs/->swagger model options)] (vector {:in "body" :name (or (common/title schema) "") @@ -55,7 +55,7 @@ (for [[k v] (-> model common/value-of stc/schema-value rsc/strict-schema) :when (s/specific-key? k) :let [rk (s/explicit-schema-key k) - json-schema (rsjs/->swagger v options :swagger)] + json-schema (rsjs/->swagger v options)] :when json-schema] (merge {:in (name in) @@ -81,11 +81,11 @@ (let [responses (p/for-map [[k v] responses :let [{:keys [schema headers]} v]] k (-> v - (cond-> schema (update-in [:schema] rsjs/->swagger options :swagger)) + (cond-> schema (update-in [:schema] rsjs/->swagger options)) (cond-> headers (update-in [:headers] (fn [headers] (if headers (->> (for [[k v] headers] - [k (rsjs/->swagger v options :swagger)]) + [k (rsjs/->swagger v options)]) (into {})))))) (update-in [:description] #(or % (:description (rsjs/json-schema-meta v)) diff --git a/test/ring/swagger/json_schema_test.clj b/test/ring/swagger/json_schema_test.clj index ab61e7e..fd48604 100644 --- a/test/ring/swagger/json_schema_test.clj +++ b/test/ring/swagger/json_schema_test.clj @@ -19,7 +19,7 @@ (s/defrecord User [age :- s/Int, keyboard :- Keyboard]) ;; Make currency return nil for testing purporses -(defmethod rsjs/convert-class java.util.Currency [_ _ _] nil) +(defmethod rsjs/convert-class java.util.Currency [_ _] nil) (facts "type transformations" (fact "mapped to nil" @@ -82,13 +82,13 @@ (fact "uses wrapped value by default with x-nullable true" (rsjs/->swagger (s/maybe Long)) => (assoc (rsjs/->swagger Long) :x-nullable true)) (fact "adds allowEmptyValue when for query and formData as defined by the spec" - (rsjs/->swagger (s/maybe Long) {:in :query} :swagger) => (assoc (rsjs/->swagger Long) :allowEmptyValue true) - (rsjs/->swagger (s/maybe Long) {:in :formData} :swagger) => (assoc (rsjs/->swagger Long) :allowEmptyValue true)) + (rsjs/->swagger (s/maybe Long) {:in :query}) => (assoc (rsjs/->swagger Long) :allowEmptyValue true) + (rsjs/->swagger (s/maybe Long) {:in :formData}) => (assoc (rsjs/->swagger Long) :allowEmptyValue true)) (fact "uses wrapped value by default with x-nullable true with body" - (rsjs/->swagger (s/maybe Long) {:in :body} :swagger) => (assoc (rsjs/->swagger Long) :x-nullable true)) + (rsjs/->swagger (s/maybe Long) {:in :body}) => (assoc (rsjs/->swagger Long) :x-nullable true)) (fact "uses wrapped value for other parameters" - (rsjs/->swagger (s/maybe Long) {:in :header} :swagger) => (rsjs/->swagger Long) - (rsjs/->swagger (s/maybe Long) {:in :path} :swagger) => (rsjs/->swagger Long))) + (rsjs/->swagger (s/maybe Long) {:in :header}) => (rsjs/->swagger Long) + (rsjs/->swagger (s/maybe Long) {:in :path}) => (rsjs/->swagger Long))) (fact "s/defrecord" (rsjs/->swagger User) => {:type "object", @@ -122,11 +122,11 @@ (fact "s/Any" (rsjs/->swagger s/Any) => {} - (rsjs/->swagger s/Any {:in :body} :swagger) => {} - (rsjs/->swagger s/Any {:in :header} :swagger) => {:type "string"} - (rsjs/->swagger s/Any {:in :path} :swagger) => {:type "string"} - (rsjs/->swagger s/Any {:in :query} :swagger) => {:type "string", :allowEmptyValue true} - (rsjs/->swagger s/Any {:in :formData} :swagger) => {:type "string", :allowEmptyValue true}) + (rsjs/->swagger s/Any {:in :body}) => {} + (rsjs/->swagger s/Any {:in :header}) => {:type "string"} + (rsjs/->swagger s/Any {:in :path}) => {:type "string"} + (rsjs/->swagger s/Any {:in :query}) => {:type "string", :allowEmptyValue true} + (rsjs/->swagger s/Any {:in :formData}) => {:type "string", :allowEmptyValue true}) (fact "s/conditional" (rsjs/->swagger (s/conditional (constantly true) Long (constantly false) String))