Skip to content

Commit 32e7728

Browse files
author
Sergei Orlov
committed
✨ Add support for image transformation in props
✨ Add support for lowering title level ✨ Add option for transforming Notion page props to frontmatter ➕ Add gatsby-source-filesystem as a peer dependency 🐛 Fix indentation of code snippets written in Markdown syntax 🐛 Fix displaying Markdown tables
1 parent 17f4d62 commit 32e7728

File tree

6 files changed

+331
-122
lines changed

6 files changed

+331
-122
lines changed

gatsby-node.js

Lines changed: 46 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,65 @@
11
const { getPages } = require("./src/notion-api/get-pages")
2-
const { getNotionPageMD } = require("./src/transformers/get-page-md")
2+
const { notionBlockToMarkdown } = require("./src/transformers/notion-block-to-markdown")
33
const { getNotionPageProperties } = require("./src/transformers/get-page-properties")
44
const { getNotionPageTitle } = require("./src/transformers/get-page-title")
55
const YAML = require("yaml")
6+
const { createRemoteFileNode } = require("gatsby-source-filesystem")
67

7-
const NODE_TYPE = "Notion"
8+
const NOTION_NODE_TYPE = "Notion"
9+
10+
exports.onCreateNode = async ({ node, actions: { createNode }, createNodeId, getCache }) => {
11+
if (node.internal.type == NOTION_NODE_TYPE) {
12+
const filesPropertyKey = Object.keys(node.properties).find(
13+
(key) => node.properties[key].type == "files",
14+
)
15+
16+
if (filesPropertyKey) {
17+
for (let i = 0; i < node.properties[filesPropertyKey].value.length; i++) {
18+
const name = node.properties[filesPropertyKey].value[i].name
19+
20+
if (name.startsWith("http")) {
21+
const fileNode = await createRemoteFileNode({
22+
url: name,
23+
parentNodeId: node.id,
24+
createNode,
25+
createNodeId,
26+
getCache,
27+
})
28+
29+
if (fileNode) {
30+
node.properties[filesPropertyKey].value[i].remoteImage___NODE = fileNode.id
31+
}
32+
}
33+
}
34+
}
35+
}
36+
}
837

938
exports.sourceNodes = async (
1039
{ actions, createContentDigest, createNodeId, reporter },
11-
pluginOptions,
40+
{ token, databaseId, propsToFrontmatter = true, lowerTitleLevel = true },
1241
) => {
13-
const pages = await getPages(
14-
{ token: pluginOptions.token, databaseId: pluginOptions.databaseId },
15-
reporter,
16-
)
17-
18-
/*
19-
if (page.properties[key].type == "rich_text") {
20-
page.properties[key].rich_text = blockToString(page.properties[key].rich_text)
21-
}
22-
*/
42+
const pages = await getPages({ token, databaseId }, reporter)
2343

2444
pages.forEach((page) => {
2545
const title = getNotionPageTitle(page)
2646
const properties = getNotionPageProperties(page)
27-
const frontmatter = Object.keys(properties).reduce(
28-
(acc, key) => {
29-
if (properties[key].type == "date") {
30-
return {
31-
...acc,
32-
[key]: properties[key].value.start,
33-
}
34-
}
35-
36-
if (properties[key].type == "rich_text") {
37-
return {
38-
...acc,
39-
[key]: blockToString(properties[key].value),
40-
}
41-
}
47+
let markdown = notionBlockToMarkdown(page, lowerTitleLevel)
4248

43-
return {
49+
if (propsToFrontmatter) {
50+
const frontmatter = Object.keys(properties).reduce(
51+
(acc, key) => ({
4452
...acc,
45-
[key]: properties[key].value,
46-
}
47-
},
48-
{ title },
49-
)
50-
const markdown = "---\n"
51-
.concat(YAML.stringify(frontmatter))
52-
.concat("\n---\n\n")
53-
.concat(getNotionPageMD(page))
53+
[key]: properties[key].value.remoteImage || properties[key].value,
54+
}),
55+
{ title },
56+
)
57+
58+
markdown = "---\n".concat(YAML.stringify(frontmatter)).concat("\n---\n\n").concat(markdown)
59+
}
5460

5561
actions.createNode({
56-
id: createNodeId(`${NODE_TYPE}-${page.id}`),
62+
id: createNodeId(`${NOTION_NODE_TYPE}-${page.id}`),
5763
title,
5864
properties,
5965
archived: page.archived,
@@ -65,7 +71,7 @@ exports.sourceNodes = async (
6571
parent: null,
6672
children: [],
6773
internal: {
68-
type: NODE_TYPE,
74+
type: NOTION_NODE_TYPE,
6975
mediaType: "text/markdown",
7076
content: markdown,
7177
contentDigest: createContentDigest(page),

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,5 +87,8 @@
8787
"statements": 80,
8888
"check-coverage": true,
8989
"all": true
90+
},
91+
"peerDependencies": {
92+
"gatsby-source-filesystem": "^3.6.0"
9093
}
9194
}

src/transformers/get-page-md.js

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

src/transformers/get-page-properties.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1+
const { blockToString } = require("../block-to-string")
2+
13
exports.getNotionPageProperties = (page) =>
24
Object.keys(page.properties).reduce((acc, key) => {
35
if (page.properties[key].type == "title") {
46
return acc
57
}
68

9+
if (page.properties[key].type == "rich_text") {
10+
page.properties[key].rich_text = blockToString(page.properties[key].rich_text)
11+
}
12+
713
return {
814
...acc,
915
[key]: {
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
const { blockToString } = require("../block-to-string")
2+
3+
const EOL_MD = "\n"
4+
5+
exports.notionBlockToMarkdown = (block, lowerTitleLevel, depth = 0) =>
6+
block.children.reduce((acc, childBlock) => {
7+
let childBlocksString = ""
8+
9+
if (childBlock.has_children) {
10+
childBlocksString = " "
11+
.repeat(depth)
12+
.concat(childBlocksString)
13+
.concat(this.notionBlockToMarkdown(childBlock, lowerTitleLevel, depth + 2))
14+
.concat(EOL_MD)
15+
}
16+
17+
if (childBlock.type == "paragraph") {
18+
const p = blockToString(childBlock.paragraph.text)
19+
20+
const isTableRow = p.startsWith("|") && p.endsWith("|")
21+
22+
const isCodeSnippetLine = block.paragraph?.text[0]?.plain_text?.startsWith("```")
23+
24+
return acc
25+
.concat(p)
26+
.concat(isTableRow || isCodeSnippetLine ? EOL_MD : EOL_MD.concat(EOL_MD))
27+
.concat(childBlocksString)
28+
}
29+
30+
if (childBlock.type.startsWith("heading_")) {
31+
const headingLevel = Number(childBlock.type.split("_")[1])
32+
33+
return acc
34+
.concat(EOL_MD)
35+
.concat(lowerTitleLevel ? "#" : "")
36+
.concat("#".repeat(headingLevel))
37+
.concat(" ")
38+
.concat(blockToString(childBlock[childBlock.type].text))
39+
.concat(EOL_MD)
40+
.concat(childBlocksString)
41+
}
42+
43+
if (childBlock.type == "to_do") {
44+
return acc
45+
.concat(`- [${childBlock.to_do.checked ? "x" : " "}] `)
46+
.concat(blockToString(childBlock.to_do.text))
47+
.concat(EOL_MD)
48+
.concat(childBlocksString)
49+
}
50+
51+
if (childBlock.type == "bulleted_list_item") {
52+
return acc
53+
.concat("* ")
54+
.concat(blockToString(childBlock.bulleted_list_item.text))
55+
.concat(EOL_MD)
56+
.concat(childBlocksString)
57+
}
58+
59+
if (childBlock.type == "numbered_list_item") {
60+
return acc
61+
.concat("1. ")
62+
.concat(blockToString(childBlock.numbered_list_item.text))
63+
.concat(EOL_MD)
64+
.concat(childBlocksString)
65+
}
66+
67+
if (childBlock.type == "toggle") {
68+
return acc
69+
.concat("<details><summary>")
70+
.concat(blockToString(childBlock.toggle.text))
71+
.concat("</summary>")
72+
.concat(childBlocksString)
73+
.concat("</details>")
74+
}
75+
76+
if (childBlock.type == "unsupported") {
77+
return acc
78+
.concat(`<!-- This block is not supported by Notion API yet. -->`)
79+
.concat(EOL_MD)
80+
.concat(childBlocksString)
81+
}
82+
83+
return acc
84+
}, "")

0 commit comments

Comments
 (0)