amazon-s3clojurescriptaws-sdk-nodejsclojurescript-javascript-interop

In Clojurescript, how do I use AWS javascript SDK to list S3 buckets?


I am just getting started with Clojurescript. I wrote some clojurescript code to use the shared aws credentials file to initialize S3 client and list buckets . However my code does not work.

(defn -main [arg1 arg2]
  (println "hello")
  (let[ creds (new AWS/SharedIniFileCredentials #js{:profile "superman"}) 
       _ (AWS/config.update creds) 
       ; dump out the accesskey to check if it has the correct profile
       _ (AWS/config.getCredentials (fn [err] (if (nil? err) (do
                                                               (println "its good")
                                                               (println AWS/config.credentials.accessKeyId)))))
       s3 (new (.-S3 AWS ))
       ] (.listBuckets s3 (fn[err buckets] (println "err: " err) (println buckets) )) ))

The AWS/config.getCredentials in the above does pick up the correct profile as seen from (println AWS/config.credentials.accessKeyId). The listbuckets code throws the following error:

#object[NodeError TypeError [ERR_INVALID_ARG_TYPE]: The "key" argument must be of type string or an instance of Buffer, TypedArray, DataView, or KeyObject. Received undefined]

I have Google AWS SDK S3 clojuresript AND is the only link I found . I used that to configure the S3 client but that does not seem to work

I would appreciate any help.


Solution

  • I checked it and the problem seems to be that SDK expects the credentials to be set before anything else, before instantiating the S3 client.

    The following works for me on a minimal project with shadow-cljs:

    (ns server.main
      (:require ["aws-sdk" :as aws]))
    
    (defn main! []
      (println "App loaded...")
      (let [creds (aws/SharedIniFileCredentials. #js {:profile "example-profile"})
            _     (set! (.-credentials aws/config) creds)
            s3    (aws/S3.)]
        (.listBuckets s3 (fn [err data]
                           (if err
                             (println "ERROR:" err)
                             (println "OK:" data))))))
    

    when I run it:

    $ node target/main.js
    
    App loaded...
    OK: #js {:Buckets #js [#js {:Name dummy-test-bucket, :CreationDate #inst "2019-05-05T17:32:17.000-00:00"} #js {:Name mydomain.com, :CreationDate #inst "2018-06-19T04:16:10.000-00:00"}], :Owner #js {:DisplayName username, :ID f63f30bc25ab3609b8d3b5be6b3a872dd2c9f7947b2d509e2338357d93e74f2}}
    

    The key was on this answer: https://stackoverflow.com/a/33175424/483566