From cac6ac3303a5bf469736688da85d2091ab9a9818 Mon Sep 17 00:00:00 2001 From: Johan Codinha Date: Thu, 23 Jan 2025 00:42:41 +1100 Subject: [PATCH 1/2] Dedicated transform-string function to handle various string formats Both StringSchema and JsonSchema (with "string" type) use a new transform-string helper. This enables structured handling of formats like uuid, date, and email, while preserving support for maxLength, pattern, and enumerations. --- src/navi/transform.clj | 49 +++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/src/navi/transform.clj b/src/navi/transform.clj index c889fdc..5e134a3 100644 --- a/src/navi/transform.clj +++ b/src/navi/transform.clj @@ -64,18 +64,36 @@ (map p/transform) (into [compose-as])))) -(extend-protocol p/Transformable - StringSchema - (p/transform [schema] - (let [content-fn string? - max-length (.getMaxLength schema) - min-length (.getMinLength schema) - properties (cond-> nil - max-length (assoc :max max-length) - min-length (assoc :min min-length)) - pattern (some-> schema .getPattern re-pattern) - enums (into [:enum] (.getEnum schema))] - (cond +(defn format->malli-predicate + "Given an OpenAPI string format, return a suitable Malli predicate for basic validation." + [fmt] + (case fmt + "uuid" uuid? + "binary" string? + "byte" string? + "date" string? + "date-time" string? + "password" string? + "email" string? + "uri" string? + "hostname" string? + "ipv4" string? + "ipv6" string? + string?)) + +(defn transform-string + "Given a StringSchema or a JsonSchema that we know is string-typed, + return a Malli schema that respects format, length constraints, pattern, and enum." + [^Schema schema] + (let [content-fn (format->malli-predicate (.getFormat schema)) + max-length (.getMaxLength schema) + min-length (.getMinLength schema) + properties (cond-> nil + max-length (assoc :max max-length) + min-length (assoc :min min-length)) + pattern (some-> schema .getPattern re-pattern) + enums (into [:enum] (.getEnum schema))] + (rcond (and properties pattern) [:and content-fn [:string properties] pattern] @@ -91,6 +109,11 @@ :else content-fn))) +(extend-protocol p/Transformable + StringSchema + (p/transform [schema] + (transform-string schema)) + UUIDSchema (p/transform [_] uuid?) @@ -125,7 +148,7 @@ "null" nil? "number" number? "object" (transform-object schema) - "string" string? + "string" (transform-string schema) (throw (IllegalArgumentException. (format "Unsupported type %s for schema %s" typ schema))))) types (.getTypes schema)] (case (count types) From ebdbf57420d8780dbe4a8f1102654e568e6dd978 Mon Sep 17 00:00:00 2001 From: Johan Codinha Date: Thu, 23 Jan 2025 00:46:18 +1100 Subject: [PATCH 2/2] typo --- src/navi/transform.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/navi/transform.clj b/src/navi/transform.clj index 5e134a3..ce956d6 100644 --- a/src/navi/transform.clj +++ b/src/navi/transform.clj @@ -93,7 +93,7 @@ min-length (assoc :min min-length)) pattern (some-> schema .getPattern re-pattern) enums (into [:enum] (.getEnum schema))] - (rcond + (cond (and properties pattern) [:and content-fn [:string properties] pattern]