Skip to content

OpenAPI & Swagger generation fail for st/spec inside s/or #291

@opqdonut

Description

@opqdonut

Repro:

(require '[clojure.spec.alpha :as s])
(require '[spec-tools.core :as st])
(require '[spec-tools.swagger.core :as swagger])
(require '[spec-tools.openapi.core :as openapi])

(s/def ::a int?)
(s/def ::b string?)
(s/def ::A (s/keys :req-un [::a]))
(s/def ::B (s/keys :req-un [::b]))

(s/def ::body (s/or :a ::A :b ::B))

(swagger/swagger-spec {::swagger/parameters {:body ::body}}) ;works
(openapi/transform ::body) ;works

(s/def ::body-wrapped (s/or :a (st/spec ::A) :b (st/spec ::B)))

(swagger/swagger-spec {::swagger/parameters {:body ::body-wrapped}}) ;fails
(openapi/transform ::body-wrapped) ;fails

The exceptions are:

(swagger)

#error {
 :cause "Don't know how to create ISeq from: clojure.lang.Keyword"
 :via
 [{:type clojure.lang.Compiler$CompilerException
   :message "Syntax error macroexpanding at (/home/joel/work/metosin/spec-tools/or-openapi-repro.clj:16:1)."
   :data #:clojure.error{:phase :execution, :line 16, :column 1, :source "/home/joel/work/metosin/spec-tools/or-openapi-repro.clj"}
   :at [clojure.lang.Compiler load "Compiler.java" 7665]}
  {:type java.lang.IllegalArgumentException
   :message "Don't know how to create ISeq from: clojure.lang.Keyword"
   :at [clojure.lang.RT seqFrom "RT.java" 557]}]
 :trace
 [[clojure.lang.RT seqFrom "RT.java" 557]
  [clojure.lang.RT seq "RT.java" 537]
  [clojure.core$seq__5467 invokeStatic "core.clj" 139]
  [clojure.core.protocols$seq_reduce invokeStatic "protocols.clj" 24]
  [clojure.core.protocols$fn__8226 invokeStatic "protocols.clj" 75]
  [clojure.core.protocols$fn__8226 invoke "protocols.clj" 75]
  [clojure.core.protocols$fn__8178$G__8173__8191 invoke "protocols.clj" 13]
  [clojure.core$reduce invokeStatic "core.clj" 6887]
  [clojure.core$reduce invoke "core.clj" 6869]
  [spec_tools.impl$unlift_keys invokeStatic "impl.cljc" 166]
  [spec_tools.impl$unlift_keys invoke "impl.cljc" 165]
  [spec_tools.swagger.core$eval3633$fn__3634 invoke "core.cljc" 85]
  [clojure.lang.MultiFn invoke "MultiFn.java" 244]
  [spec_tools.visitor$eval3249$fn__3250 invoke "visitor.cljc" 149]
  [clojure.lang.MultiFn invoke "MultiFn.java" 239]
  [spec_tools.visitor$visit invokeStatic "visitor.cljc" 52]
  [spec_tools.visitor$visit invoke "visitor.cljc" 26]
  [spec_tools.visitor$eval3100$fn__3101$fn__3106 invoke "visitor.cljc" 64]
  [clojure.core$mapv$fn__8535 invoke "core.clj" 6980]
  [clojure.core.protocols$iter_reduce invokeStatic "protocols.clj" 49]
  [clojure.core.protocols$fn__8238 invokeStatic "protocols.clj" 75]
  [clojure.core.protocols$fn__8238 invoke "protocols.clj" 75]
  [clojure.core.protocols$fn__8178$G__8173__8191 invoke "protocols.clj" 13]
  [clojure.core$reduce invokeStatic "core.clj" 6887]
  [clojure.core$mapv invokeStatic "core.clj" 6971]
  [clojure.core$mapv invoke "core.clj" 6971]
  [spec_tools.visitor$eval3100$fn__3101 invoke "visitor.cljc" 64]
  [clojure.lang.MultiFn invoke "MultiFn.java" 239]
  [spec_tools.visitor$visit invokeStatic "visitor.cljc" 52]
  [spec_tools.visitor$visit invoke "visitor.cljc" 26]
  [spec_tools.swagger.core$transform invokeStatic "core.cljc" 101]
  [spec_tools.swagger.core$transform invoke "core.cljc" 92]
  [spec_tools.swagger.core$eval3652$fn__3653 invoke "core.cljc" 110]
  [clojure.lang.MultiFn invoke "MultiFn.java" 234]
  [spec_tools.swagger.core$eval3702$fn__3703$fn__3705 invoke "core.cljc" 147]
  [clojure.core$map$fn__5935 invoke "core.clj" 2772]
  [clojure.lang.LazySeq sval "LazySeq.java" 42]
  [clojure.lang.LazySeq seq "LazySeq.java" 51]
  [clojure.lang.RT seq "RT.java" 535]
  [clojure.core$seq__5467 invokeStatic "core.clj" 139]
  [clojure.core$apply invokeStatic "core.clj" 662]
  [clojure.core$mapcat invokeStatic "core.clj" 2800]
  [clojure.core$mapcat doInvoke "core.clj" 2800]
  [clojure.lang.RestFn invoke "RestFn.java" 423]
  [spec_tools.swagger.core$eval3702$fn__3703 invoke "core.cljc" 147]
  [clojure.lang.MultiFn invoke "MultiFn.java" 244]
  [spec_tools.swagger.core$expand_qualified_keywords$fn__3719$fn__3720 invoke "core.cljc" 170]
  [clojure.lang.PersistentArrayMap kvreduce "PersistentArrayMap.java" 429]
  [clojure.core$fn__8525 invokeStatic "core.clj" 6909]
  [clojure.core$fn__8525 invoke "core.clj" 6889]
  [clojure.core.protocols$fn__8257$G__8252__8266 invoke "protocols.clj" 175]
  [clojure.core$reduce_kv invokeStatic "core.clj" 6920]
  [clojure.core$reduce_kv invoke "core.clj" 6911]
  [spec_tools.swagger.core$expand_qualified_keywords$fn__3719 invoke "core.cljc" 167]
  [clojure.walk$walk invokeStatic "walk.clj" 50]
  [clojure.walk$postwalk invokeStatic "walk.clj" 53]
  [clojure.walk$postwalk invoke "walk.clj" 53]
  [spec_tools.swagger.core$expand_qualified_keywords invokeStatic "core.cljc" 164]
  [spec_tools.swagger.core$expand_qualified_keywords invoke "core.cljc" 162]
  [spec_tools.swagger.core$swagger_spec invokeStatic "core.cljc" 189]
  [spec_tools.swagger.core$swagger_spec invoke "core.cljc" 181]
  [spec_tools.swagger.core$swagger_spec invokeStatic "core.cljc" 187]
  [spec_tools.swagger.core$swagger_spec invoke "core.cljc" 181]
  ...

(openapi)

#error {
 :cause "Don't know how to create ISeq from: clojure.lang.Keyword"
 :via
 [{:type clojure.lang.Compiler$CompilerException
   :message "Syntax error macroexpanding at (/home/joel/work/metosin/spec-tools/or-openapi-repro.clj:18:1)."
   :data #:clojure.error{:phase :execution, :line 18, :column 1, :source "/home/joel/work/metosin/spec-tools/or-openapi-repro.clj"}
   :at [clojure.lang.Compiler load "Compiler.java" 7665]}
  {:type java.lang.IllegalArgumentException
   :message "Don't know how to create ISeq from: clojure.lang.Keyword"
   :at [clojure.lang.RT seqFrom "RT.java" 557]}]
 :trace
 [[clojure.lang.RT seqFrom "RT.java" 557]
  [clojure.lang.RT seq "RT.java" 537]
  [clojure.core$seq__5467 invokeStatic "core.clj" 139]
  [clojure.core.protocols$seq_reduce invokeStatic "protocols.clj" 24]
  [clojure.core.protocols$fn__8226 invokeStatic "protocols.clj" 75]
  [clojure.core.protocols$fn__8226 invoke "protocols.clj" 75]
  [clojure.core.protocols$fn__8178$G__8173__8191 invoke "protocols.clj" 13]
  [clojure.core$reduce invokeStatic "core.clj" 6887]
  [clojure.core$reduce invoke "core.clj" 6869]
  [spec_tools.impl$unlift_keys invokeStatic "impl.cljc" 166]
  [spec_tools.impl$unlift_keys invoke "impl.cljc" 165]
  [spec_tools.openapi.core$eval3766$fn__3767 invoke "core.cljc" 34]
  [clojure.lang.MultiFn invoke "MultiFn.java" 244]
  [spec_tools.visitor$eval3249$fn__3250 invoke "visitor.cljc" 149]
  [clojure.lang.MultiFn invoke "MultiFn.java" 239]
  [spec_tools.visitor$visit invokeStatic "visitor.cljc" 52]
  [spec_tools.visitor$visit invoke "visitor.cljc" 26]
  [spec_tools.visitor$eval3100$fn__3101$fn__3106 invoke "visitor.cljc" 64]
  [clojure.core$mapv$fn__8535 invoke "core.clj" 6980]
  [clojure.core.protocols$iter_reduce invokeStatic "protocols.clj" 49]
  [clojure.core.protocols$fn__8238 invokeStatic "protocols.clj" 75]
  [clojure.core.protocols$fn__8238 invoke "protocols.clj" 75]
  [clojure.core.protocols$fn__8178$G__8173__8191 invoke "protocols.clj" 13]
  [clojure.core$reduce invokeStatic "core.clj" 6887]
  [clojure.core$mapv invokeStatic "core.clj" 6971]
  [clojure.core$mapv invoke "core.clj" 6971]
  [spec_tools.visitor$eval3100$fn__3101 invoke "visitor.cljc" 64]
  [clojure.lang.MultiFn invoke "MultiFn.java" 239]
  [spec_tools.visitor$visit invokeStatic "visitor.cljc" 52]
  [spec_tools.visitor$visit invoke "visitor.cljc" 26]
  [spec_tools.openapi.core$transform invokeStatic "core.cljc" 47]
  [spec_tools.openapi.core$transform invoke "core.cljc" 42]
  [spec_tools.openapi.core$transform invokeStatic "core.cljc" 45]
  [spec_tools.openapi.core$transform invoke "core.cljc" 42]
  ...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions