diff --git a/CHANGELOG.md b/CHANGELOG.md index a5f11b073..58100995d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - #883, Binary output support for RPC - @steve-chavez - #885, Postgres COMMENTs on SCHEMA/TABLE/COLUMN are used for OpenAPI - @ldesgoui - #907, Ability to embed using a specific relation when there are multiple between tables - @ruslantalpa +- #930, Split table comment on newline to get OpenAPI operation summary and description - @daurnimator ### Fixed diff --git a/src/PostgREST/OpenAPI.hs b/src/PostgREST/OpenAPI.hs index 0cefbce8e..e38cda47a 100644 --- a/src/PostgREST/OpenAPI.hs +++ b/src/PostgREST/OpenAPI.hs @@ -6,17 +6,18 @@ module PostgREST.OpenAPI ( , pickProxy ) where +import Control.Arrow ((&&&)) import Control.Lens import Data.Aeson (decode, encode) import Data.HashMap.Strict.InsOrd (InsOrdHashMap, fromList) import Data.Maybe (fromJust) import qualified Data.Set as Set import Data.String (IsString (..)) -import Data.Text (unpack, pack, init, tail, toLower, intercalate, append) +import Data.Text (unpack, pack, init, tail, toLower, intercalate, append, dropWhile, breakOn) import Network.URI (parseURI, isAbsoluteURI, URI (..), URIAuth (..)) -import Protolude hiding ((&), Proxy, get, intercalate) +import Protolude hiding ((&), Proxy, get, intercalate, dropWhile) import Data.Swagger @@ -183,9 +184,14 @@ makeRowFilters tn = map (makeRowFilter tn) makePathItem :: (Table, [Column], [Text]) -> (FilePath, PathItem) makePathItem (t, cs, _) = ("/" ++ unpack tn, p $ tableInsertable t) where + -- Use first line of table description as summary; rest as description (if present) + -- We strip leading newlines from description so that users can include a blank line between summary and description + (tSum, tDesc) = fmap fst &&& fmap (dropWhile (=='\n') . snd) $ + breakOn "\n" <$> tableDescription t tOp = (mempty :: Operation) & tags .~ Set.fromList [tn] - & description .~ tableDescription t + & summary .~ tSum + & description .~ mfilter (/="") tDesc getOp = tOp & parameters .~ map ref (rs <> ["select", "order", "range", "rangeUnit", "offset", "limit", "preferCount"]) & at 206 ?~ "Partial Content" diff --git a/test/Feature/StructureSpec.hs b/test/Feature/StructureSpec.hs index 7ae4a6d7a..5bec5fbd6 100644 --- a/test/Feature/StructureSpec.hs +++ b/test/Feature/StructureSpec.hs @@ -33,13 +33,27 @@ spec = do r <- simpleBody <$> get "/" let method s = key "paths" . key "/child_entities" . key s + childGetSummary = r ^? method "get" . key "summary" + childGetDescription = r ^? method "get" . key "description" getParameters = r ^? method "get" . key "parameters" postResponse = r ^? method "post" . key "responses" . key "201" . key "description" patchResponse = r ^? method "patch" . key "responses" . key "204" . key "description" deleteResponse = r ^? method "delete" . key "responses" . key "204" . key "description" + let grandChildGet s = key "paths" . key "/grandchild_entities" . key "get" . key s + grandChildGetSummary = r ^? grandChildGet "summary" + grandChildGetDescription = r ^? grandChildGet "description" + liftIO $ do + childGetSummary `shouldBe` Just "child_entities comment" + + childGetDescription `shouldBe` Nothing + + grandChildGetSummary `shouldBe` Just "grandchild_entities summary" + + grandChildGetDescription `shouldBe` Just "grandchild_entities description\nthat spans\nmultiple lines" + getParameters `shouldBe` Just [aesonQQ| [ diff --git a/test/fixtures/schema.sql b/test/fixtures/schema.sql index 7a7a51557..4313a8599 100755 --- a/test/fixtures/schema.sql +++ b/test/fixtures/schema.sql @@ -1220,6 +1220,13 @@ comment on table child_entities is 'child_entities comment'; comment on column child_entities.id is 'child_entities id comment'; comment on column child_entities.name is 'child_entities name comment'; +comment on table grandchild_entities is +$$grandchild_entities summary + +grandchild_entities description +that spans +multiple lines$$; + -- Used for testing that having the same return column name as the proc name -- doesn't conflict with the required output, details in #901 create function test.test() returns table(test text, value int) as $$