billstclair / elm-s3

A pure-Elm interface to Amazon's Simple Storage Service and Digital Ocean's Spaces
MIT License
7 stars 5 forks source link

Custom endpoint support #8

Open jpds opened 1 year ago

jpds commented 1 year ago

I'd like to use this library with a custom S3-compliant endpoint (such as Garage/Minio). In order to see if this works, I attempted this change:

diff --git a/example/S3Example.elm b/example/S3Example.elm
index 0987334..0e1e522 100644
--- a/example/S3Example.elm
+++ b/example/S3Example.elm
@@ -168,6 +168,7 @@ deleteObject model =
 defaultAccount : Account
 defaultAccount =
     { name = "No account"
+    , endpoint = Nothing
     , region = Nothing
     , accessKey = ""
     , secretKey = ""
diff --git a/src/S3.elm b/src/S3.elm
index c4f9a6f..c03efd3 100644
--- a/src/S3.elm
+++ b/src/S3.elm
@@ -211,6 +211,12 @@ encodeAccount account =
     JE.object <|
         List.concat
             [ [ ( "name", JE.string account.name ) ]
+            , case account.endpoint of
+                Nothing ->
+                    []
+
+                Just endpoint ->
+                    [ ( "endpoint", JE.string endpoint ) ]
             , case account.region of
                 Nothing ->
                     []
@@ -233,8 +239,13 @@ encodeAccount account =
 -}
 accountDecoder : Decoder Account
 accountDecoder =
-    JD.map6 Account
+    JD.map7 Account
         (JD.field "name" JD.string)
+        (JD.oneOf
+            [ JD.field "endpoint" (JD.nullable JD.string)
+            , JD.succeed Nothing
+            ]
+        )
         (JD.oneOf
             [ JD.field "region" (JD.nullable JD.string)
             , JD.succeed Nothing
@@ -281,6 +292,9 @@ protocol : Config.Protocol
 protocol =
     Config.REST_XML

+forcedEndpoint : String
+forcedEndpoint = "s3.example.com"
+

 {-| Make an `AWS.Service.Service` for an `S3.Account`.

@@ -528,11 +542,10 @@ requestUrl account req =
         ( service, request ) =
             fudgeRequest account req

-        { hostResolver, endpoint, endpointPrefix } =
-            service
+        {-{ hostResolver, endpoint, endpointPrefix } =
+            service-}

-        host =
-            hostResolver endpoint endpointPrefix
+        host = forcedEndpoint
     in
     "https://"
         ++ host
diff --git a/src/S3/Types.elm b/src/S3/Types.elm
index a39c7b1..5e014a1 100644
--- a/src/S3/Types.elm
+++ b/src/S3/Types.elm
@@ -60,6 +60,7 @@ type Error
 -}
 type alias Account =
     { name : String
+    , endpoint : Maybe String
     , region : Maybe String
     , isDigitalOcean : Bool
     , accessKey : String

However, although the app renders - everything returns a HttpError NetworkError.

billstclair commented 1 year ago

I am away from home for the rest of May. I doubt I'll look at this until early in June.