@@ -26,6 +26,8 @@ import Control.Arrow (second)
2626import Control.Lens (makeLenses, over, traversed, (%~),
2727 (&), (.~), (<>~), (^.), (|>))
2828import qualified Control.Monad.Omega as Omega
29+import Data.Aeson (ToJSON(..))
30+import Data.Aeson.Encode.Pretty (encodePretty)
2931import Data.ByteString.Conversion (ToByteString, toByteString)
3032import Data.ByteString.Lazy.Char8 (ByteString)
3133import qualified Data.CaseInsensitive as CI
@@ -367,6 +369,37 @@ docsWith opts intros (ExtraInfo endpoints) p =
367369docsWithIntros :: HasDocs layout => [DocIntro] -> Proxy layout -> API
368370docsWithIntros intros = docsWith defaultDocOptions intros mempty
369371
372+-- | Prettify generated JSON documentation.
373+--
374+-- @
375+-- 'docs' ('pretty' ('Proxy' :: 'Proxy' MyAPI))
376+-- @
377+pretty :: Proxy layout -> Proxy (Pretty layout)
378+pretty Proxy = Proxy
379+
380+data PrettyJSON
381+
382+instance Accept PrettyJSON where
383+ contentType _ = "application" M.// "json"
384+
385+instance ToJSON a => MimeRender PrettyJSON a where
386+ mimeRender _ = encodePretty
387+
388+-- | Replace all JSON content types with PrettyJSON.
389+-- Kind-polymorphic so it can operate on kinds * and [*].
390+type family Pretty (layout :: k) :: k where
391+ Pretty (x :<|> y) = Pretty x :<|> Pretty y
392+ Pretty (x :> y) = Pretty x :> Pretty y
393+ Pretty (Get cs r) = Get (Pretty cs) r
394+ Pretty (Post cs r) = Post (Pretty cs) r
395+ Pretty (Put cs r) = Put (Pretty cs) r
396+ Pretty (Delete cs r) = Delete (Pretty cs) r
397+ Pretty (Patch cs r) = Patch (Pretty cs) r
398+ Pretty (ReqBody cs r) = ReqBody (Pretty cs) r
399+ Pretty (JSON ': xs) = PrettyJSON ': xs
400+ Pretty (x ': xs) = x ': Pretty xs
401+ Pretty x = x
402+
370403-- | The class that abstracts away the impact of API combinators
371404-- on documentation generation.
372405class HasDocs layout where