packages feed

servant-elm 0.3.0.1 → 0.4.0.0

raw patch · 12 files changed

+108/−31 lines, 12 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Servant.Elm: Dynamic :: UrlPrefix
+ Servant.Elm: Static :: Text -> UrlPrefix
+ Servant.Elm: data UrlPrefix
+ Servant.Elm.Internal.Generate: Dynamic :: UrlPrefix
+ Servant.Elm.Internal.Generate: Static :: Text -> UrlPrefix
+ Servant.Elm.Internal.Generate: data UrlPrefix
- Servant.Elm: ElmOptions :: Text -> Options -> [ElmDatatype] -> [ElmDatatype] -> ElmOptions
+ Servant.Elm: ElmOptions :: UrlPrefix -> Options -> [ElmDatatype] -> [ElmDatatype] -> ElmOptions
- Servant.Elm: [urlPrefix] :: ElmOptions -> Text
+ Servant.Elm: [urlPrefix] :: ElmOptions -> UrlPrefix
- Servant.Elm.Internal.Generate: ElmOptions :: Text -> Options -> [ElmDatatype] -> [ElmDatatype] -> ElmOptions
+ Servant.Elm.Internal.Generate: ElmOptions :: UrlPrefix -> Options -> [ElmDatatype] -> [ElmDatatype] -> ElmOptions
- Servant.Elm.Internal.Generate: [urlPrefix] :: ElmOptions -> Text
+ Servant.Elm.Internal.Generate: [urlPrefix] :: ElmOptions -> UrlPrefix
- Servant.Elm.Internal.Generate: mkArgs :: Req ElmDatatype -> Doc
+ Servant.Elm.Internal.Generate: mkArgs :: ElmOptions -> Req ElmDatatype -> Doc

Files

CHANGELOG.md view
@@ -1,3 +1,9 @@+0.4.0.0+-------+* Allow passing the base URL dynamically in Elm. (#20)+* Don't use `toString` on `Text` parameters. (domenkozar) (#23, #24)+* Fix query parameter generation. (domenkozar) (#25)+ 0.3.0.1 ------- * Prefix generated function arguments to ensure valid Elm identifiers (#21)
README.md view
@@ -84,18 +84,17 @@         |> required "name" string  getBooksByBookId : Int -> Http.Request (Book)-getBooksByBookId bookId =+getBooksByBookId capture_bookId =     Http.request         { method =             "GET"         , headers =-            [ Http.header "Content-Type" "application/json"-            ]+            []         , url =             String.join "/"                 [ ""                 , "books"-                , bookId |> toString |> Http.encodeUri+                , capture_bookId |> toString |> Http.encodeUri                 ]         , body =             Http.emptyBody
examples/books/generate.hs view
@@ -8,7 +8,7 @@ import           GHC.Generics (Generic) import           Servant.API  ((:<|>), (:>), Capture, Get, JSON, Post, ReqBody) import           Servant.Elm  (ElmOptions (..), ElmType, Proxy (Proxy),-                               defElmImports, defElmOptions,+                               UrlPrefix (Static), defElmImports, defElmOptions,                                generateElmForAPIWith)  data Book = Book@@ -22,7 +22,7 @@            :<|> "books" :> Capture "bookId" Int :> Get '[JSON] Book  myElmOpts :: ElmOptions-myElmOpts = defElmOptions { urlPrefix = "http://localhost:8000" }+myElmOpts = defElmOptions { urlPrefix = Static "http://localhost:8000" }  spec :: Spec spec = Spec ["Generated", "BooksApi"]
examples/e2e-tests/generate.hs view
@@ -10,12 +10,12 @@ import           Servant.API  ((:<|>), (:>), Capture, Get, GetNoContent, JSON,                                NoContent, Post, QueryParam, ReqBody) import           Servant.Elm  (ElmOptions (..), ElmType, Proxy (Proxy),-                               defElmImports, defElmOptions,+                               UrlPrefix (Static), defElmImports, defElmOptions,                                generateElmForAPIWith)   myElmOpts :: ElmOptions-myElmOpts = defElmOptions { urlPrefix =  "https://httpbin.org" }+myElmOpts = defElmOptions { urlPrefix = Static "https://httpbin.org" }   data MessageBody = MessageBody
examples/giphy/generate.hs view
@@ -9,7 +9,7 @@                                toElmDecoderSourceWith, toElmTypeSourceWith) import           GHC.Generics (Generic) import           Servant.API  ((:>), Get, JSON, QueryParam)-import           Servant.Elm  (ElmOptions (..), ElmType, Proxy (Proxy),+import           Servant.Elm  (ElmOptions (..), ElmType, Proxy (Proxy), UrlPrefix(Static),                                defElmImports, defElmOptions,                                generateElmForAPIWith) @@ -40,7 +40,7 @@ myElmOpts =   defElmOptions     { urlPrefix =-        "http://api.giphy.com/v1/gifs"+        Static "http://api.giphy.com/v1/gifs"     , elmExportOptions =         options     }
servant-elm.cabal view
@@ -1,5 +1,5 @@ name:                servant-elm-version:             0.3.0.1+version:             0.4.0.0 synopsis:            Automatically derive Elm functions to query servant webservices. description:         Please see README.md homepage:            http://github.com/mattjbray/servant-elm#readme
src/Servant/Elm.hs view
@@ -15,6 +15,7 @@        ( generateElmForAPI        , generateElmForAPIWith        , ElmOptions(..)+       , UrlPrefix(..)        , defElmOptions        , defElmImports        -- * Convenience re-exports from the "Elm" module@@ -25,8 +26,8 @@        , Proxy(Proxy)        ) where -import           Servant.Elm.Internal.Generate (ElmOptions (..), defElmImports,-                                                defElmOptions,+import           Servant.Elm.Internal.Generate (ElmOptions (..), UrlPrefix (..),+                                                defElmImports, defElmOptions,                                                 generateElmForAPI,                                                 generateElmForAPIWith) 
src/Servant/Elm/Internal/Generate.hs view
@@ -28,9 +28,12 @@   { {- | The protocol, host and any path prefix to be used as the base for all     requests. -    Example: @"https://mydomain.com/api/v1"@+    Example: @Static "https://mydomain.com/api/v1"@++    When @Dynamic@, the generated Elm functions take the base URL as the first+    argument.     -}-    urlPrefix             :: T.Text+    urlPrefix             :: UrlPrefix   , elmExportOptions      :: Elm.Options     -- ^ Options to pass to elm-export   , emptyResponseElmTypes :: [ElmDatatype]@@ -40,13 +43,18 @@   }  +data UrlPrefix+  = Static T.Text+  | Dynamic++ {-| Default options for generating Elm code.  The default options are:  > { urlPrefix =->     ""+>     Static "" > , elmExportOptions = >     Elm.defaultOptions > , emptyResponseElmTypes =@@ -57,7 +65,7 @@ -} defElmOptions :: ElmOptions defElmOptions = ElmOptions-  { urlPrefix = ""+  { urlPrefix = Static ""   , elmExportOptions = Elm.defaultOptions   , emptyResponseElmTypes =       [ Elm.toElmType NoContent@@ -65,6 +73,7 @@       ]   , stringElmTypes =       [ Elm.toElmType ("" :: String)+      , Elm.toElmType ("" :: T.Text)       ]   } @@ -156,7 +165,7 @@       mkTypeSignature opts request      args =-      mkArgs request+      mkArgs opts request      letParams =       mkLetParams opts request@@ -168,12 +177,19 @@ mkTypeSignature :: ElmOptions -> F.Req ElmDatatype -> Doc mkTypeSignature opts request =   (hsep . punctuate " ->" . concat)-    [ headerTypes+    [ catMaybes [urlPrefixType]+    , headerTypes     , urlCaptureTypes     , queryTypes     , catMaybes [bodyType, returnType]     ]   where+    urlPrefixType :: Maybe Doc+    urlPrefixType =+        case (urlPrefix opts) of+          Dynamic -> Just "String"+          Static _ -> Nothing+     elmTypeRef :: ElmDatatype -> Doc     elmTypeRef eType =       stext (Elm.toElmTypeRefWith (elmExportOptions opts) eType)@@ -238,11 +254,16 @@   mkArgs-  :: F.Req ElmDatatype+  :: ElmOptions+  -> F.Req ElmDatatype   -> Doc-mkArgs request =+mkArgs opts request =   (hsep . concat) $-    [ -- Headers+    [ -- Dynamic url prefix+      case urlPrefix opts of+        Dynamic -> ["urlBase"]+        Static _ -> []+    , -- Headers       [ elmHeaderArg header       | header <- request ^. F.reqHeaders       ]@@ -286,7 +307,7 @@                 "toString >> "           in               name <$>-              indent 4 ("|> Maybe.map" <+> parens (toStringSrc <> "Http.encodeUri >> (++)" <+> dquotes (name <> equals)) <$>+              indent 4 ("|> Maybe.map" <+> parens (toStringSrc <> "Http.encodeUri >> (++)" <+> dquotes (elmName <> equals)) <$>                         "|> Maybe.withDefault" <+> dquotes empty)          F.Flag ->@@ -300,8 +321,8 @@             indent 4 ("|> List.map" <+> parens (backslash <> "val ->" <+> dquotes (name <> "[]=") <+> "++ (val |> toString |> Http.encodeUri)") <$>                       "|> String.join" <+> dquotes "&")       where-        name =-          elmQueryArg qarg+        name = elmQueryArg qarg+        elmName= qarg ^. F.queryArgName . F.argName . to (stext . F.unPathSegment)   mkRequest :: ElmOptions -> F.Req ElmDatatype -> Doc@@ -382,8 +403,10 @@ mkUrl opts segments =   "String.join" <+> dquotes "/" <$>   (indent i . elmList)-    ( dquotes (stext (urlPrefix opts))-    : map segmentToDoc segments)+    ( case urlPrefix opts of+        Dynamic -> "urlBase"+        Static url -> dquotes (stext url)+      : map segmentToDoc segments)   where      segmentToDoc :: F.Segment ElmDatatype -> Doc
test/Common.hs view
@@ -3,6 +3,7 @@ {-# LANGUAGE TypeOperators #-} module Common where +import           Data.Text    (Text) import           Data.Aeson   (ToJSON) import           Data.Proxy   (Proxy(Proxy)) import           Elm          (ElmType)@@ -28,7 +29,7 @@          :> Capture "id" Int          :> Get '[JSON] Book   :<|> "books"-         :> Capture "title" String+         :> Capture "title" Text          :> Get '[JSON] Book   :<|> "books"          :> QueryFlag "published"
test/GenerateSpec.hs view
@@ -12,11 +12,12 @@ import           Data.Text                 (Text) import qualified Data.Text                 as T import qualified Data.Text.IO              as T+import           Servant.API               ((:>), Get, JSON) import           Servant.Elm import           Test.Hspec                (Spec, describe, hspec, it) import           Test.HUnit                (Assertion, assertBool) -import Common (testApi)+import           Common                    (testApi)   main :: IO ()@@ -64,6 +65,25 @@                               "import Http\n" <>                               "import Json.Decode exposing (..)\n\n\n")]                   let generated = map (<> "\n") (generateElmForAPI testApi)+                  generated `itemsShouldBe` expected+           it "with dynamic URLs" $+               do expected <-+                      mapM+                          (\(fpath,header) -> do+                               source <- T.readFile fpath+                               return (fpath, header, source))+                          [ ( "test/elm-sources/getOneWithDynamicUrlSource.elm"+                            , "module GetOneWithDynamicUrlSource exposing (..)\n\n" <>+                              "import Http\n" <>+                              "import Json.Decode exposing (..)\n\n\n")]+                  let generated =+                          map+                              (<> "\n")+                              (generateElmForAPIWith+                                   (defElmOptions+                                    { urlPrefix = Dynamic+                                    })+                                   (Proxy :: Proxy ("one" :> Get '[JSON] Int)))                   generated `itemsShouldBe` expected  itemsShouldBe :: [Text] -> [(String, Text, Text)] -> IO ()
test/elm-sources/getBooksSource.elm view
@@ -14,10 +14,10 @@                   else                     ""                 , query_sort-                    |> Maybe.map (Http.encodeUri >> (++) "query_sort=")+                    |> Maybe.map (Http.encodeUri >> (++) "sort=")                     |> Maybe.withDefault ""                 , query_year-                    |> Maybe.map (toString >> Http.encodeUri >> (++) "query_year=")+                    |> Maybe.map (toString >> Http.encodeUri >> (++) "year=")                     |> Maybe.withDefault ""                 , query_filters                     |> List.map (\val -> "query_filters[]=" ++ (val |> toString |> Http.encodeUri))
+ test/elm-sources/getOneWithDynamicUrlSource.elm view
@@ -0,0 +1,27 @@+module GetOneWithDynamicUrlSource exposing (..)++import Http+import Json.Decode exposing (..)+++getOne : String -> Http.Request (Int)+getOne urlBase =+    Http.request+        { method =+            "GET"+        , headers =+            []+        , url =+            String.join "/"+                [ urlBase+                , "one"+                ]+        , body =+            Http.emptyBody+        , expect =+            Http.expectJson int+        , timeout =+            Nothing+        , withCredentials =+            False+        }