packages feed

notion-client 0.1.0.1 → 0.2.0.0

raw patch · 8 files changed

+81/−13 lines, 8 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Notion.V1: [retrievePageMarkdown] :: Methods -> PageID -> Maybe Bool -> IO PageMarkdown
+ Notion.V1.Pages: PageMarkdown :: PageID -> Text -> Bool -> Vector UUID -> PageMarkdown
+ Notion.V1.Pages: [markdown] :: PageMarkdown -> Text
+ Notion.V1.Pages: [truncated] :: PageMarkdown -> Bool
+ Notion.V1.Pages: [unknownBlockIds] :: PageMarkdown -> Vector UUID
+ Notion.V1.Pages: data PageMarkdown
+ Notion.V1.Pages: instance Data.Aeson.Types.FromJSON.FromJSON Notion.V1.Pages.PageMarkdown
+ Notion.V1.Pages: instance Data.Aeson.Types.ToJSON.ToJSON Notion.V1.Pages.PageMarkdown
+ Notion.V1.Pages: instance GHC.Internal.Generics.Generic Notion.V1.Pages.PageMarkdown
+ Notion.V1.Pages: instance GHC.Internal.Show.Show Notion.V1.Pages.PageMarkdown
- Notion.V1: Methods :: (CreateDatabase -> IO DatabaseObject) -> (DatabaseID -> IO DatabaseObject) -> (DatabaseID -> UpdateDatabase -> IO DatabaseObject) -> (DatabaseID -> QueryDatabase -> IO (ListOf PageObject)) -> (DataSourceID -> IO DataSourceObject) -> (CreateDataSource -> IO DataSourceObject) -> (DataSourceID -> UpdateDataSource -> IO DataSourceObject) -> (DataSourceID -> QueryDataSource -> IO (ListOf PageObject)) -> (CreatePage -> IO PageObject) -> (PageID -> IO PageObject) -> (PageID -> UpdatePage -> IO PageObject) -> (BlockID -> IO BlockObject) -> (BlockID -> BlockContent -> IO BlockObject) -> (ParentID -> Maybe Natural -> Maybe Text -> IO (ListOf BlockObject)) -> (ParentID -> AppendBlockChildren -> IO (ListOf BlockObject)) -> (BlockID -> IO BlockObject) -> (UserID -> IO UserObject) -> (Maybe Natural -> Maybe Text -> IO (ListOf UserObject)) -> IO UserObject -> (SearchRequest -> IO (ListOf Value)) -> (CreateComment -> IO CommentObject) -> (Maybe BlockID -> Maybe Text -> Maybe Natural -> IO (ListOf CommentObject)) -> Methods
+ Notion.V1: Methods :: (CreateDatabase -> IO DatabaseObject) -> (DatabaseID -> IO DatabaseObject) -> (DatabaseID -> UpdateDatabase -> IO DatabaseObject) -> (DatabaseID -> QueryDatabase -> IO (ListOf PageObject)) -> (DataSourceID -> IO DataSourceObject) -> (CreateDataSource -> IO DataSourceObject) -> (DataSourceID -> UpdateDataSource -> IO DataSourceObject) -> (DataSourceID -> QueryDataSource -> IO (ListOf PageObject)) -> (CreatePage -> IO PageObject) -> (PageID -> IO PageObject) -> (PageID -> UpdatePage -> IO PageObject) -> (PageID -> Maybe Bool -> IO PageMarkdown) -> (BlockID -> IO BlockObject) -> (BlockID -> BlockContent -> IO BlockObject) -> (ParentID -> Maybe Natural -> Maybe Text -> IO (ListOf BlockObject)) -> (ParentID -> AppendBlockChildren -> IO (ListOf BlockObject)) -> (BlockID -> IO BlockObject) -> (UserID -> IO UserObject) -> (Maybe Natural -> Maybe Text -> IO (ListOf UserObject)) -> IO UserObject -> (SearchRequest -> IO (ListOf Value)) -> (CreateComment -> IO CommentObject) -> (Maybe BlockID -> Maybe Text -> Maybe Natural -> IO (ListOf CommentObject)) -> Methods
- Notion.V1.DataSources: DataSourceObject :: DataSourceID -> POSIXTime -> POSIXTime -> UserReference -> UserReference -> Vector RichText -> Vector RichText -> Value -> Text -> Parent -> Maybe Parent -> Bool -> Maybe Bool -> Maybe Bool -> Maybe Text -> Maybe Icon -> Maybe Cover -> ObjectType -> DataSourceObject
+ Notion.V1.DataSources: DataSourceObject :: DataSourceID -> POSIXTime -> POSIXTime -> UserReference -> UserReference -> Vector RichText -> Vector RichText -> Value -> Text -> Parent -> Maybe Parent -> Maybe Bool -> Maybe Bool -> Maybe Bool -> Maybe Text -> Maybe Icon -> Maybe Cover -> ObjectType -> DataSourceObject
- Notion.V1.Pages: [id] :: SelectOption -> Maybe Text
+ Notion.V1.Pages: [id] :: PageMarkdown -> PageID
- Notion.V1.Pages: type API = "pages" :> Capture "page_id" PageID :> Get '[JSON] PageObject :<|> ReqBody '[JSON] CreatePage :> Post '[JSON] PageObject :<|> Capture "page_id" PageID :> ReqBody '[JSON] UpdatePage :> Patch '[JSON] PageObject
+ Notion.V1.Pages: type API = "pages" :> Capture "page_id" PageID :> Get '[JSON] PageObject :<|> ReqBody '[JSON] CreatePage :> Post '[JSON] PageObject :<|> Capture "page_id" PageID :> ReqBody '[JSON] UpdatePage :> Patch '[JSON] PageObject :<|> Capture "page_id" PageID :> "markdown" :> QueryParam "include_transcript" Bool :> Get '[JSON] PageMarkdown

Files

CHANGELOG.md view
@@ -1,5 +1,18 @@ # Changelog for notion-client +## 0.2.0.0 (2026-03-29)++### Breaking Changes+* Bump Notion API version from `2025-09-03` to `2026-03-11`+* Change `DataSourceObject.archived` from `Bool` to `Maybe Bool` (field no longer guaranteed in API responses)++### New Features+* Add `PageMarkdown` type and `retrievePageMarkdown` method for `GET /v1/pages/{page_id}/markdown`+* Support optional `include_transcript` query parameter for markdown retrieval++### Bug Fixes+* Handle API rename of `archived` to `is_archived` in responses for `PageObject`, `BlockObject`, `DatabaseObject`, and `DataSourceObject`+ ## 0.1.0.1 (2026-03-29)  ### Bug Fixes
notion-client.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.4 name:               notion-client-version:            0.1.0.1+version:            0.2.0.0 synopsis:           Type-safe Haskell client for the Notion API description:   This package provides comprehensive and type-safe bindings
src/Notion/V1.hs view
@@ -48,7 +48,7 @@ import Notion.V1.Databases (CreateDatabase, DatabaseID, DatabaseObject, QueryDatabase, UpdateDatabase) import Notion.V1.Databases qualified as Databases import Notion.V1.ListOf (ListOf (..))-import Notion.V1.Pages (CreatePage, PageID, PageObject, UpdatePage)+import Notion.V1.Pages (CreatePage, PageID, PageMarkdown, PageObject, UpdatePage) import Notion.V1.Pages qualified as Pages import Notion.V1.Search (SearchRequest) import Notion.V1.Search qualified as Search@@ -76,7 +76,7 @@   Methods makeMethods clientEnv token = Methods {..}   where-    notionVersion = "2025-09-03" -- Notion API version with data source support+    notionVersion = "2026-03-11" -- Notion API version with markdown content support     -- If you experience 400 errors, check for updated versions at     -- https://developers.notion.com/reference/versioning     ( ( createDatabase@@ -92,6 +92,7 @@         :<|> ( retrievePage                  :<|> createPage                  :<|> updatePage+                 :<|> retrievePageMarkdown                )         :<|> ( retrieveBlock                  :<|> updateBlock@@ -140,6 +141,11 @@     createPage :: CreatePage -> IO PageObject,     retrievePage :: PageID -> IO PageObject,     updatePage :: PageID -> UpdatePage -> IO PageObject,+    retrievePageMarkdown ::+      PageID ->+      Maybe Bool ->+      -- \^ include_transcript+      IO PageMarkdown,     -- \* Blocks     retrieveBlock :: BlockID -> IO BlockObject,     updateBlock :: BlockID -> Blocks.BlockContent -> IO BlockObject,
src/Notion/V1/Blocks.hs view
@@ -11,9 +11,11 @@   ) where -import Data.Aeson ((.:), (.=))+import Control.Applicative ((<|>))+import Data.Aeson ((.:), (.:?), (.=)) import Data.Aeson qualified as Aeson import Data.Aeson.Key qualified as Key+import Data.Maybe (fromMaybe) import Notion.Prelude import Notion.V1.Common (BlockID, ObjectType (..), Parent) import Notion.V1.ListOf (ListOf)@@ -48,7 +50,7 @@       createdBy <- o .: "created_by"       lastEditedBy <- o .: "last_edited_by"       hasChildren <- o .: "has_children"-      archived <- o .: "archived"+      archived <- fmap (fromMaybe False) (o .:? "is_archived" <|> o .:? "archived")       type_ <- o .: "type"       -- Content is stored under a field named after the block type (e.g., "heading_1", "paragraph")       content <- o .: Key.fromText type_
src/Notion/V1/DataSources.hs view
@@ -15,6 +15,7 @@   ) where +import Control.Applicative ((<|>)) import Data.Aeson ((.:), (.:?)) import Notion.Prelude import Notion.V1.Common (Cover, Icon, ObjectType, Parent, UUID)@@ -40,7 +41,7 @@     url :: Text,     parent :: Parent,     databaseParent :: Maybe Parent,-    archived :: Bool,+    archived :: Maybe Bool,     isInline :: Maybe Bool,     inTrash :: Maybe Bool,     publicUrl :: Maybe Text,@@ -66,7 +67,7 @@       url <- o .: "url"       parent <- o .: "parent"       databaseParent <- o .:? "database_parent"-      archived <- o .: "archived"+      archived <- o .:? "is_archived" <|> o .:? "archived"       isInline <- o .:? "is_inline"       inTrash <- o .:? "in_trash"       publicUrl <- o .:? "public_url"
src/Notion/V1/Databases.hs view
@@ -14,6 +14,7 @@   ) where +import Control.Applicative ((<|>)) import Data.Aeson ((.:), (.:?)) import Notion.Prelude import Notion.V1.Common (Cover, Icon, ObjectType (..), Parent, UUID)@@ -81,7 +82,7 @@       cover <- o .:? "cover"       url <- o .: "url"       parent <- o .: "parent"-      archived <- o .:? "archived"+      archived <- o .:? "is_archived" <|> o .:? "archived"       isInline <- o .:? "is_inline"       inTrash <- o .:? "in_trash"       isLocked <- o .:? "is_locked"
src/Notion/V1/Pages.hs view
@@ -13,15 +13,20 @@     mkCreatePage,     mkUpdatePage, +    -- * Markdown+    PageMarkdown (..),+     -- * Servant     API,   ) where +import Control.Applicative ((<|>)) import Data.Aeson ((.:), (.:?), (.=)) import Data.Aeson qualified as Aeson import Data.Aeson.Key qualified as Key import Data.Aeson.KeyMap qualified as KeyMap+import Data.Maybe (fromMaybe) import Notion.Prelude hiding (Number) import Notion.V1.Common (Cover, Icon, ObjectType (..), Parent, UUID) import Notion.V1.Users (UserReference)@@ -60,7 +65,7 @@       cover <- o .:? "cover"       icon <- o .:? "icon"       parent <- o .: "parent"-      archived <- o .: "archived"+      archived <- fmap (fromMaybe False) (o .:? "is_archived" <|> o .:? "archived")       inTrash <- o .: "in_trash"       properties <- o .: "properties"       url <- o .: "url"@@ -267,6 +272,23 @@ instance ToJSON SelectOption where   toJSON = genericToJSON aesonOptions +-- | Response from @GET \/v1\/pages\/{page_id}\/markdown@+--+-- Contains the page content rendered as Notion-flavored enhanced markdown.+data PageMarkdown = PageMarkdown+  { id :: PageID,+    markdown :: Text,+    truncated :: Bool,+    unknownBlockIds :: Vector UUID+  }+  deriving stock (Generic, Show)++instance FromJSON PageMarkdown where+  parseJSON = genericParseJSON aesonOptions++instance ToJSON PageMarkdown where+  toJSON = genericToJSON aesonOptions+ -- | Servant API type API =   "pages"@@ -277,4 +299,8 @@            :<|> Capture "page_id" PageID            :> ReqBody '[JSON] UpdatePage            :> Patch '[JSON] PageObject+           :<|> Capture "page_id" PageID+           :> "markdown"+           :> QueryParam "include_transcript" Bool+           :> Get '[JSON] PageMarkdown        )
tasty/Main.hs view
@@ -2,7 +2,9 @@  import Data.Text qualified as Text import Notion.V1+import Notion.V1.Common (UUID (..)) import Notion.V1.ListOf (ListOf (..))+import Notion.V1.Pages (PageMarkdown (..)) import Notion.V1.Search (SearchRequest (..)) import Notion.V1.Users (UserObject (..)) import System.Environment qualified as Environment@@ -31,13 +33,24 @@       clientEnv <- getClientEnv "https://api.notion.com/v1"       let methods = makeMethods clientEnv (Text.pack token) +      mPageId <- lookupEnv "NOTION_TEST_PAGE_ID"++      let markdownTests = case mPageId of+            Just pageId ->+              [ testCase "Retrieve page as markdown" $+                  testRetrievePageMarkdown methods (Text.pack pageId)+              ]+            Nothing -> []+       pure $         testGroup           "Notion API Tests"-          [ testCase "Retrieve current user" $ testRetrieveCurrentUser methods,-            testCase "List users" $ testListUsers methods,-            testCase "Timestamp parsing works" $ testSearchAPI methods-          ]+          ( [ testCase "Retrieve current user" $ testRetrieveCurrentUser methods,+              testCase "List users" $ testListUsers methods,+              testCase "Timestamp parsing works" $ testSearchAPI methods+            ]+              <> markdownTests+          )  testRetrieveCurrentUser :: Methods -> Assertion testRetrieveCurrentUser Methods {retrieveMyUser} = do@@ -65,6 +78,12 @@   _ <- search searchParams   -- If this test runs without errors, it means timestamp parsing works   assertBool "Search should run without timestamp parsing errors" True++testRetrievePageMarkdown :: Methods -> Text.Text -> Assertion+testRetrievePageMarkdown Methods {retrievePageMarkdown} pageId = do+  result <- retrievePageMarkdown (UUID pageId) Nothing+  let PageMarkdown {markdown = md} = result+  assertBool "Markdown content should not be empty" (not $ Text.null md)  lookupEnv :: String -> IO (Maybe String) lookupEnv var = Environment.lookupEnv var