Skip to content

Commit 80cdba3

Browse files
committed
feat: Replace parseText with getTextFromBlock
1 parent 923dc6e commit 80cdba3

File tree

5 files changed

+130
-117
lines changed

5 files changed

+130
-117
lines changed

src/get-notion-object-title.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
RichTextItemResponse,
66
} from '@notionhq/client/build/src/api-endpoints';
77

8-
import { parseText } from './parse-text';
8+
import { getTextFromBlock } from './getTextFromBlock';
99

1010
export type Icon =
1111
| {
@@ -75,5 +75,5 @@ export const getNotionObjectTitle = (
7575
return `${icon}${title}`;
7676
}
7777

78-
return parseText(notionObject);
78+
return getTextFromBlock(notionObject);
7979
};

src/getTextFromBlock.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export function getTextFromBlock(input: unknown): string;

src/getTextFromBlock.js

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/**
2+
* This file originates from https://github.com/makenotion/notion-sdk-js/tree/main/examples/parse-text-from-any-block-type
3+
*
4+
* Credit to Jess Mitchell @jessmitch42
5+
*/
6+
7+
/*
8+
---------------------------------------------------------------------------
9+
*/
10+
// Take rich text array from a block child that supports rich text and return the plain text.
11+
// Note: All rich text objects include a plain_text field.
12+
const getPlainTextFromRichText = richText => {
13+
return richText.map(t => t.plain_text).join("")
14+
// Note: A page mention will return "Undefined" as the page name if the page has not been shared with the integration. See: https://developers.notion.com/reference/block#mention
15+
}
16+
17+
// Use the source URL and optional caption from media blocks (file, video, etc.)
18+
const getMediaSourceText = block => {
19+
let source, caption
20+
21+
if (block[block.type].external) {
22+
source = block[block.type].external.url
23+
} else if (block[block.type].file) {
24+
source = block[block.type].file.url
25+
} else if (block[block.type].url) {
26+
source = block[block.type].url
27+
} else {
28+
source = "[Missing case for media block types]: " + block.type
29+
}
30+
// If there's a caption, return it with the source
31+
if (block[block.type].caption.length) {
32+
caption = getPlainTextFromRichText(block[block.type].caption)
33+
return caption + ": " + source
34+
}
35+
// If no caption, just return the source URL
36+
return source
37+
}
38+
39+
// Get the plain text from any block type supported by the public API.
40+
export const getTextFromBlock = block => {
41+
let text
42+
43+
// Get rich text from blocks that support it
44+
if (block[block.type].rich_text) {
45+
// This will be an empty string if it's an empty line.
46+
text = getPlainTextFromRichText(block[block.type].rich_text)
47+
}
48+
// Get text for block types that don't have rich text
49+
else {
50+
switch (block.type) {
51+
case "unsupported":
52+
// The public API does not support all block types yet
53+
text = "[Unsupported block type]"
54+
break
55+
case "bookmark":
56+
text = block.bookmark.url
57+
break
58+
case "child_database":
59+
text = block.child_database.title
60+
// Use "Query a database" endpoint to get db rows: https://developers.notion.com/reference/post-database-query
61+
// Use "Retrieve a database" endpoint to get additional properties: https://developers.notion.com/reference/retrieve-a-database
62+
break
63+
case "child_page":
64+
text = block.child_page.title
65+
break
66+
case "embed":
67+
case "video":
68+
case "file":
69+
case "image":
70+
case "pdf":
71+
text = getMediaSourceText(block)
72+
break
73+
case "equation":
74+
text = block.equation.expression
75+
break
76+
case "link_preview":
77+
text = block.link_preview.url
78+
break
79+
case "synced_block":
80+
// Provides ID for block it's synced with.
81+
text = block.synced_block.synced_from
82+
? "This block is synced with a block with the following ID: " +
83+
block.synced_block.synced_from[block.synced_block.synced_from.type]
84+
: "Source sync block that another blocked is synced with."
85+
break
86+
case "table":
87+
// Only contains table properties.
88+
// Fetch children blocks for more details.
89+
text = "Table width: " + block.table.table_width
90+
break
91+
case "table_of_contents":
92+
// Does not include text from ToC; just the color
93+
text = "ToC color: " + block.table_of_contents.color
94+
break
95+
case "breadcrumb":
96+
case "column_list":
97+
case "divider":
98+
text = "No text available"
99+
break
100+
default:
101+
text = "[Needs case added]"
102+
break
103+
}
104+
}
105+
// Blocks with the has_children property will require fetching the child blocks. (Not included in this example.)
106+
// e.g. nested bulleted lists
107+
if (block.has_children) {
108+
// For now, we'll just flag there are children blocks.
109+
text = text + " (Has children)"
110+
}
111+
// Includes block type for readability. Update formatting as needed.
112+
return block.type + ": " + text
113+
}
114+
115+
async function retrieveBlockChildren(id) {
116+
console.log("Retrieving blocks (async)...")
117+
const blocks = []
118+
119+
// Use iteratePaginatedAPI helper function to get all blocks first-level blocks on the page
120+
for await (const block of iteratePaginatedAPI(notion.blocks.children.list, {
121+
block_id: id, // A page ID can be passed as a block ID: https://developers.notion.com/docs/working-with-page-content#modeling-content-as-blocks
122+
})) {
123+
blocks.push(block)
124+
}
125+
126+
return blocks
127+
}

src/parse-text.d.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/parse-text.js

Lines changed: 0 additions & 114 deletions
This file was deleted.

0 commit comments

Comments
 (0)