Fork me on GitHub
#schema
<
2023-06-22
>
rpatrelle13:06:33

Hello, I'm trying to work with both s/conditional and abstract-map but it does not work as I expect. I want to use s/conditional to distinguish 2 kinds of sftp connections and use abstract-map to distinguish 2 kinds of transfer types. the code is:

(def base-sftp-schema
  {:name s/Str
   :account ObjectId
   :type (s/eq "sftp")
   :host s/Str
   :port (s/maybe s/Int)
   :path (s/maybe s/Str)
   :user s/Str})

(def SftpSchema
  (letfn [(login-mode= [x] #(= x (:login_mode %)))]
    (s/conditional
     (login-mode= "password") (merge base-sftp-schema
                                     {:type (s/eq "sftp")
                                      :login_mode (s/eq "password")
                                      :password s/Str})

     (login-mode= "private_key") (merge base-sftp-schema
                                        {:type (s/eq "sftp")
                                         :login_mode (s/eq "private_key")
                                         :credentials_key s/Str}))))

(def TransferCreateBody
  (abm/abstract-map-schema :type {:account ObjectId
                                  :name s/Str}))

(abm/extend-schema GcsTransferCreateBody TransferCreateBody ["gcs"]
                   {:bucket_name s/Str
                    (? :path) s/Str
                    :credentials_key s/Str})

(abm/extend-schema SftpTransferCreateBody TransferCreateBody ["sftp"]
                   SftpSchema)
When I test SftpSchema alone, everything is ok:
(s/validate SftpSchema {:type "sftp"
                          :account (ObjectId.)
                          :name "Transport SFTP"
                          :host ""
                          :port 22
                          :path "/export/data"
                          :user "fifou"
                          :login_mode "password"
                          :password "secret"})
=> {:path "/export/data",
 :password "secret",
 :login_mode "password",
 :name "Transport SFTP",
 :type "sftp",
 :port 22,
 :account #oid"649442876a5b1f11d8b13d93",
 :host "",
 :user "fifou"}
But when I test the TransferCreateBody , result is a failure:
(s/validate TransferCreateBody {:type "sftp"
                                  :account (ObjectId.)
                                  :name "Transport SFTP"
                                  :host ""
                                  :port 22
                                  :path "/export/data"
                                  :user "fifou"
                                  :login_mode "password"
                                  :password "secret"})
=> Execution error (IllegalArgumentException) at schema.core/eval18272$fn$G (core.clj:110).
No implementation of method: :spec of protocol: #'schema.core/Schema found for class: nil
Can someone tell me what I am doing wrong? 🙏