packages feed

servant-docs 0.11.9 → 0.12

raw patch · 6 files changed

+96/−34 lines, 6 filesdep ~aesondep ~basedep ~base-compatnew-uploader

Dependency ranges changed: aeson, base, base-compat, hashable, lens, servant, tasty, text, transformers

Files

CHANGELOG.md view
@@ -1,6 +1,15 @@ [The latest version of this document is on GitHub.](https://github.com/haskell-servant/servant/blob/master/servant-docs/CHANGELOG.md) [Changelog for `servant` package contains significant entries for all core packages.](https://github.com/haskell-servant/servant/blob/master/servant/CHANGELOG.md) +0.12+----++### Significant changes++- Generate sample cURL requests+  ([#1401](https://github.com/haskell-servant/servant/pull/1401/files)).+  Breaking change: requires sample header values to be supplied with `headers`.+ 0.11.9 ------ 
example/greet.hs view
@@ -75,7 +75,7 @@ -- API specification type TestApi =        -- GET /hello/:name?capital={true, false}  returns a Greet as JSON or PlainText-       "hello" :> Capture "name" Text :> QueryParam "capital" Bool :> Get '[JSON, PlainText] Greet+       "hello" :> Capture "name" Text :> Header "X-Num-Fairies" Int :> QueryParam "capital" Bool :> Get '[JSON, PlainText] Greet         -- POST /greet with a Greet as JSON in the request body,        --             returns a Greet as JSON@@ -93,9 +93,9 @@ extra :: ExtraInfo TestApi extra =     extraInfo (Proxy :: Proxy ("greet" :> Capture "greetid" Text :> Delete '[JSON] NoContent)) $-             defAction & headers <>~ ["unicorns"]+             defAction & headers <>~ [("X-Num-Unicorns", "1")]                        & notes   <>~ [ DocNote "Title" ["This is some text"]-                                     , DocNote "Second secton" ["And some more"]+                                     , DocNote "Second section" ["And some more"]                                      ]  -- Generate the data that lets us have API docs. This@@ -109,4 +109,4 @@ docsGreet = docsWith defaultDocOptions [intro1, intro2] extra testApi  main :: IO ()-main = putStrLn $ markdown docsGreet+main = putStrLn $ markdownWith (defRenderingOptions { _renderCurlBasePath = Just "http://localhost:80" }) docsGreet
servant-docs.cabal view
@@ -1,6 +1,6 @@-cabal-version:       >=1.10+cabal-version:       2.2 name:                servant-docs-version:             0.11.9+version:             0.12  synopsis:            generate API docs for your servant webservice category:            Servant, Web@@ -13,13 +13,13 @@  homepage:            http://docs.servant.dev/ bug-reports:         http://github.com/haskell-servant/servant/issues-license:             BSD3+license:             BSD-3-Clause license-file:        LICENSE author:              Servant Contributors maintainer:          haskell-servant-maintainers@googlegroups.com copyright:           2014-2016 Zalora South East Asia Pte Ltd, 2016-2019 Servant Contributors build-type:          Simple-tested-with: GHC ==8.0.2 || ==8.2.2 || ==8.4.4 || ==8.6.5 || ==8.8.4 || ==8.10.2 || ==9.0.1+tested-with: GHC ==8.6.5 || ==8.8.4 || ==8.10.2 || ==9.0.1  extra-source-files:   CHANGELOG.md@@ -47,12 +47,12 @@    -- Servant dependencies   build-depends:-      servant            >= 0.18 && <0.19+      servant            >= 0.18 && <0.20    -- Other dependencies: Lower bound around what is in the latest Stackage LTS.   -- Here can be exceptions if we really need features from the newer versions.   build-depends:-      aeson                >= 1.4.1.0  && < 1.6+      aeson                >= 1.4.1.0  && < 3     , aeson-pretty         >= 0.8.5    && < 0.9     , base-compat          >= 0.10.5   && < 0.12     , case-insensitive     >= 1.2.0.11 && < 1.3@@ -102,7 +102,7 @@    -- Additional dependencies   build-depends:-      tasty         >= 1.1.0.4  && < 1.3,+      tasty         >= 1.1.0.4  && < 1.5,       tasty-golden  >= 2.3.2    && < 2.4,       tasty-hunit   >= 0.10.0.1 && < 0.11,       transformers  >= 0.5.2.0  && < 0.6
src/Servant/Docs/Internal.hs view
@@ -25,16 +25,14 @@ import           Control.Arrow                  (second) import           Control.Lens-                 (makeLenses, mapped, over, set, traversed, view, (%~), (&),-                 (.~), (<>~), (^.), (|>))+                 (makeLenses, mapped, each, over, set, to, toListOf, traversed, view,+                 _1, (%~), (&), (.~), (<>~), (^.), (|>)) import qualified Data.ByteString.Char8      as BSC import           Data.ByteString.Lazy.Char8                  (ByteString) import qualified Data.CaseInsensitive       as CI import           Data.Foldable-                 (toList)-import           Data.Foldable-                 (fold)+                 (fold, toList) import           Data.Hashable                  (Hashable) import           Data.HashMap.Strict@@ -52,13 +50,14 @@                  (comparing) import           Data.Proxy                  (Proxy (Proxy))-import           Data.Semigroup-                 (Semigroup (..)) import           Data.String.Conversions                  (cs) import           Data.Text                  (Text, unpack) import           GHC.Generics+                 (Generic, Rep, K1(K1), M1(M1), U1(U1), V1,+                 (:*:)((:*:)), (:+:)(L1, R1))+import qualified GHC.Generics               as G import           GHC.TypeLits import           Servant.API import           Servant.API.ContentTypes@@ -295,7 +294,7 @@ data Action = Action   { _authInfo :: [DocAuthentication]         -- user supplied info   , _captures :: [DocCapture]                -- type collected + user supplied info-  , _headers  :: [Text]                      -- type collected+  , _headers  :: [HTTP.Header]               -- type collected   , _params   :: [DocQueryParam]             -- type collected + user supplied info   , _fragment :: Maybe DocFragment           -- type collected + user supplied info   , _notes    :: [DocNote]                   -- user supplied@@ -356,12 +355,14 @@ -- --   @since 0.11.1 data RenderingOptions = RenderingOptions-  { _requestExamples  :: !ShowContentTypes+  { _requestExamples    :: !ShowContentTypes     -- ^ How many content types to display for request body examples?-  , _responseExamples :: !ShowContentTypes+  , _responseExamples   :: !ShowContentTypes     -- ^ How many content types to display for response body examples?-  , _notesHeading     :: !(Maybe String)+  , _notesHeading       :: !(Maybe String)     -- ^ Optionally group all 'notes' together under a common heading.+  , _renderCurlBasePath :: !(Maybe String)+    -- ^ Optionally render example curl requests under a common base path (e.g. `http://localhost:80`).   } deriving (Show)  -- | Default API generation options.@@ -373,9 +374,10 @@ --   @since 0.11.1 defRenderingOptions :: RenderingOptions defRenderingOptions = RenderingOptions-  { _requestExamples  = AllContentTypes-  , _responseExamples = AllContentTypes-  , _notesHeading     = Nothing+  { _requestExamples    = AllContentTypes+  , _responseExamples   = AllContentTypes+  , _notesHeading       = Nothing+  , _renderCurlBasePath = Nothing   }  -- gimme some lenses@@ -412,7 +414,7 @@ -- > extra :: ExtraInfo TestApi -- > extra = -- >     extraInfo (Proxy :: Proxy ("greet" :> Capture "greetid" Text :> Delete)) $--- >              defAction & headers <>~ ["unicorns"]+-- >              defAction & headers <>~ [("X-Num-Unicorns", 1)] -- >                        & notes   <>~ [ DocNote "Title" ["This is some text"] -- >                                      , DocNote "Second section" ["And some more"] -- >                                      ]@@ -507,7 +509,7 @@  -- | Default sample Generic-based inputs/outputs. defaultSamples :: forall a. (Generic a, GToSample (Rep a)) => Proxy a -> [(Text, a)]-defaultSamples _ = second to <$> gtoSamples (Proxy :: Proxy (Rep a))+defaultSamples _ = second G.to <$> gtoSamples (Proxy :: Proxy (Rep a))  -- | @'ToSample'@ for Generics. --@@ -643,7 +645,7 @@ -- --   @since 0.11.1 markdownWith :: RenderingOptions -> API -> String-markdownWith RenderingOptions{..}  api = unlines $+markdownWith RenderingOptions{..} api = unlines $        introsStr (api ^. apiIntros)     ++ (concatMap (uncurry printEndpoint) . sort . HM.toList $ api ^. apiEndpoints) @@ -654,11 +656,12 @@           notesStr (action ^. notes) ++           authStr (action ^. authInfo) ++           capturesStr (action ^. captures) ++-          headersStr (action ^. headers) +++          headersStr (toListOf (headers . each . _1 . to (T.pack . BSC.unpack . CI.original)) action) ++           paramsStr meth (action ^. params) ++           fragmentStr (action ^. fragment) ++           rqbodyStr (action ^. rqtypes) (action ^. rqbody) ++           responseStr (action ^. response) +++          maybe [] (curlStr endpoint (action ^. headers) (action ^. rqbody)) _renderCurlBasePath ++           []            where str = "## " ++ BSC.unpack meth@@ -814,7 +817,6 @@                 ("text", "css") -> "css"                 (_, _) -> "" -         contentStr mime_type body =           "" :           "```" <> markdownForType mime_type :@@ -839,6 +841,36 @@                   xs        ->                     formatBodies _responseExamples xs +        curlStr :: Endpoint -> [HTTP.Header] -> [(Text, M.MediaType, ByteString)] -> String -> [String]+        curlStr endpoint hdrs reqBodies basePath =+          [  "### Sample Request:"+          , ""+          , "```bash"+          , "curl -X" ++ BSC.unpack (endpoint ^. method) ++ " \\"+          ] <>+          maybe [] pure mbMediaTypeStr <>+          headersStrs <>+          maybe [] pure mbReqBodyStr <>+          [  "  " ++ basePath ++ showPath (endpoint ^. path)+          , "```"+          , ""+          ]++          where escapeQuotes :: String -> String+                escapeQuotes = concatMap $ \c -> case c of+                  '\"' -> "\\\""+                  _ -> [c]+                mbReqBody = listToMaybe reqBodies+                mbMediaTypeStr = mkMediaTypeStr <$> mbReqBody+                headersStrs = mkHeaderStr <$> hdrs+                mbReqBodyStr = mkReqBodyStr <$> mbReqBody+                mkMediaTypeStr (_, media_type, _) =+                  "  -H \"Content-Type: " ++ show media_type ++ "\" \\"+                mkHeaderStr (hdrName, hdrVal) =+                  "  -H \"" ++ escapeQuotes (cs (CI.original hdrName)) ++ ": " +++                  escapeQuotes (cs hdrVal) ++ "\" \\"+                mkReqBodyStr (_, _, body) = "  -d \"" ++ escapeQuotes (cs body) ++ "\" \\"+ -- * Instances  -- | The generated docs for @a ':<|>' b@ just appends the docs@@ -977,14 +1009,17 @@           status = fromInteger $ natVal (Proxy :: Proxy status)           p = Proxy :: Proxy a -instance (KnownSymbol sym, HasDocs api)+instance (ToHttpApiData a, ToSample a, KnownSymbol sym, HasDocs api)       => HasDocs (Header' mods sym a :> api) where   docsFor Proxy (endpoint, action) =     docsFor subApiP (endpoint, action')      where subApiP = Proxy :: Proxy api-          action' = over headers (|> headername) action-          headername = T.pack $ symbolVal (Proxy :: Proxy sym)+          action' = over headers (|> (headerName, headerVal)) action+          headerName = CI.mk . cs $ symbolVal (Proxy :: Proxy sym)+          headerVal = case toSample (Proxy :: Proxy a) of+            Just x -> cs $ toHeader x+            Nothing -> "<no header sample provided>"  instance (KnownSymbol sym, ToParam (QueryParam' mods sym a), HasDocs api)       => HasDocs (QueryParam' mods sym a :> api) where
src/Servant/Docs/Internal/Pretty.hs view
@@ -18,6 +18,7 @@ import           Network.HTTP.Media                  ((//)) import           Servant.API+import           Servant.API.Verbs  -- | PrettyJSON content type. data PrettyJSON@@ -46,6 +47,24 @@     Pretty (Put cs r)     = Put     (Pretty cs) r     Pretty (Delete cs r)  = Delete  (Pretty cs) r     Pretty (Patch cs r)   = Patch   (Pretty cs) r+    Pretty (GetPartialContent cs r)      = GetPartialContent      (Pretty cs) r+    Pretty (PutResetContent cs r)        = PutResetContent        (Pretty cs) r+    Pretty (PatchResetContent cs r)      = PatchResetContent      (Pretty cs) r+    Pretty (DeleteResetContent cs r)     = DeleteResetContent     (Pretty cs) r+    Pretty (PostResetContent cs r)       = PostResetContent       (Pretty cs) r+    Pretty (GetResetContent cs r)        = GetResetContent        (Pretty cs) r+    Pretty (PutNonAuthoritative cs r)    = PutNonAuthoritative    (Pretty cs) r+    Pretty (PatchNonAuthoritative cs r)  = PatchNonAuthoritative  (Pretty cs) r+    Pretty (DeleteNonAuthoritative cs r) = DeleteNonAuthoritative (Pretty cs) r+    Pretty (PostNonAuthoritative cs r)   = PostNonAuthoritative   (Pretty cs) r+    Pretty (GetNonAuthoritative cs r)    = GetNonAuthoritative    (Pretty cs) r+    Pretty (PutAccepted cs r)            = PutAccepted            (Pretty cs) r+    Pretty (PatchAccepted cs r)          = PatchAccepted          (Pretty cs) r+    Pretty (DeleteAccepted cs r)         = DeleteAccepted         (Pretty cs) r+    Pretty (PostAccepted cs r)           = PostAccepted           (Pretty cs) r+    Pretty (GetAccepted cs r)            = GetAccepted            (Pretty cs) r+    Pretty (PutCreated cs r)             = PutCreated             (Pretty cs) r+    Pretty (PostCreated cs r)            = PostCreated            (Pretty cs) r     Pretty (ReqBody cs r) = ReqBody (Pretty cs) r     Pretty (JSON ': xs)   = PrettyJSON ': xs     Pretty (x ': xs)      = x ': Pretty xs
test/Servant/DocsSpec.hs view
@@ -130,7 +130,6 @@       md `shouldContain` "\"dt1field1\":\"field 1\""     it "contains response samples - dt1field2" $       md `shouldContain` "\"dt1field2\":13"-     it "contains request body samples" $       md `shouldContain` "17"