feat(page): enrich page view JSON with metadata via official API#37
feat(page): enrich page view JSON with metadata via official API#37coseto6125 wants to merge 1 commit into
Conversation
Extend `notion-cli page view --json` with the metadata fields the MCP `notion-fetch` tool does not expose: CreatedTime, LastEditedTime, CreatedBy, LastEditedBy, ParentType, ParentID, Archived, and Icon. When an official API token is configured (via `auth api setup` or NOTION_API_TOKEN), the CLI makes a supplementary GET /pages/<id> call to the Notion REST API and merges the result into the output Page. Without a token, the command behaves exactly as before — the metadata fields remain at their zero values. Failures in the metadata fetch (missing token, API error, network issue) are deliberately silent: the primary MCP-sourced fields (ID, Title, URL, Content, Comments) are still rendered so page view remains usable even when the API fallback is misconfigured. Non-JSON output paths (default text rendering, --raw) do not trigger the extra API call, keeping the common case free of network overhead. Refs lox#17 (MCP-first + REST-fallback architecture).
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e1f7804f38
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| switch parent.Type { | ||
| case "page_id": | ||
| return "page", parent.PageID | ||
| case "database_id": | ||
| return "database", parent.DatabaseID |
There was a problem hiding this comment.
Handle data_source parent IDs in metadata mapping
This switch only maps database_id, but with newer Notion API versions pages in databases commonly come back as parent.type = "data_source_id"; in that case parentFromMetadata falls through and returns an empty ParentID. The new page view --json enrichment therefore drops parent IDs for data-source-backed pages, which breaks the advertised ParentType/ParentID metadata for a large class of pages.
Useful? React with 👍 / 👎.
Summary
page view --jsontoday omits page metadata (timestamps, authors, parent, icon, archived state) because the MCPnotion-fetchtool doesn't expose those fields — theoutput.Pagestruct hasCreatedTime/LastEditedTimebut they're left as zero values.This PR adds an opt-in enrichment path: when an official API token is configured (via
auth api setuporNOTION_API_TOKEN),page view --jsonmakes a supplementaryGET /pages/<id>call to the Notion REST API and merges the result into the JSON output.When no token is configured, the command behaves exactly as before — no network overhead, no behavior change.
This continues the MCP-first + REST-fallback pattern established in #17 and the groundwork laid by #28.
Changes
internal/api/client.goPageMetadata,PartialUser,PageIcon,PageParenttypes mapping the Notion REST API responseGetPageMetadata(ctx, pageID)method callingGET /pages/<id>internal/output/types.goCreatedByandLastEditedBystring fields toPage(timestamps were already defined)cmd/page.gorenderFetchedPageViewcalls a newloadPageMetadatahelper when JSON output is requested, and merges metadata viaapplyPageMetadatabefore callingprintViewedPageFnloadPageMetadatais swappable (test seam) and swallows errors from missing token / API failure so the primary output is never blocked--rawmodes skip the API call entirelycmd/page_view_test.gointernal/api/client_test.goREADME.mdBehavior matrix
--json--json--rawTest plan
go build ./...cleango test ./...passes (existing + new tests)go vet ./...cleangofmt -l .emptyNOTION_API_TOKEN=ntn_xxx notion-cli page view <url> --json | jq '{CreatedBy, LastEditedBy, Archived}'returns populated fieldsNotes
page viewUXArchivedcombinesarchived || in_trashsince the Notion API returns both flagsRefs #17