feat(page): 'page markdown' + 'page set-markdown' (server-side markdown I/O)#47
Merged
Conversation
Closes #37. Wraps the two 2025 Notion endpoints that do server-side markdown I/O on a full page: GET /v1/pages/:id/markdown → notion page markdown <id> PATCH /v1/pages/:id/markdown → notion page set-markdown <id> ### page markdown Prints a page's content as markdown. Strictly better than `block list --md` for page-level dumps: the server handles toggles, columns, synced blocks, and databases-as-pages uniformly and always matches what the Notion UI shows. notion page markdown <id> notion page markdown <id> > page.md notion page markdown <id> --out page.md notion page markdown <id> --format json # full response incl. truncated flag Surfaces Notion's 'truncated' flag and 'unknown_block_ids' as stderr notes in default output so silent partial renders don't go unnoticed. ### page set-markdown Updates a page from markdown in one API call. Supports all four mutation modes Notion's PATCH endpoint accepts: --replace (default) replace_content: overwrite whole page --append insert_content at end --after <anchor> insert_content after ellipsis anchor ("start...end") --range <anchor> replace_content_range bounded by ellipsis anchor --file <path> (use '-' for stdin) --text <str> inline markdown --allow-deleting-content pass allow flag for destructive modes Because Notion handles the full markdown → blocks conversion server-side, this is the cleanest way to write long documents — the 100-children batching (#21) doesn't apply to set-markdown. ### Implementation Two pure helpers isolate the fiddly bits for unit testing without network: - buildSetMarkdownBody: produces the correct envelope for each mode; rejects ambiguous flag combinations up front. - readMarkdownSource: picks the source (--file / --text / stdin); same mutual-exclusion rules as the rest of the CLI. ### Tests - Exhaustive buildSetMarkdownBody coverage across all four modes + allow_deleting_content + multi-mode rejection. - readMarkdownSource: required / conflict / file / stdin / file-missing. ### Smoke Verified end-to-end against a real workspace: replace via --file, append --text, markdown read with --out, stdin replace, and multi-mode rejection all behave as documented.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #37. Wraps Notion's 2025 endpoints:
GET /v1/pages/:id/markdown→notion page markdown <id>PATCH /v1/pages/:id/markdown→notion page set-markdown <id>page markdown
block list --mdfor page-level dumps).--out <path>writes directly to file.truncated/unknown_block_idsas stderr notes.page set-markdown
--replace(default),--append,--after <anchor>,--range <anchor>.--file <path>(use-for stdin) or--text <str>.--allow-deleting-contentfor destructive modes.Smoke: replace → append → read-back → stdin replace → multi-mode rejection all pass against a real page.