Skip to content

Commit

Permalink
[render] Download internal images
Browse files Browse the repository at this point in the history
  • Loading branch information
Xennis committed May 29, 2024
1 parent 8c11648 commit be6e027
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 8 deletions.
3 changes: 3 additions & 0 deletions examples/nextjs/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,6 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts

# Images downloaded from CMS
public/cms/*
Empty file.
40 changes: 39 additions & 1 deletion examples/nextjs/src/lib/fetchers.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,56 @@
import { unstable_cache } from "next/cache"
import { fetchBlocksChildren } from "@react-notion-cms/render"
import { Client } from "@notionhq/client"
import { statSync, writeFileSync } from "node:fs"
import nextConfig from "../../next.config.mjs"

const notionClient = new Client({
auth: process.env.NOTION_ACCESS_TOKEN,
})

export const getCachedPageContent = unstable_cache(
async (blockId: string) => {
return fetchBlocksChildren(notionClient, blockId)
return fetchBlocksChildren(
notionClient,
{
block_id: blockId,
page_size: 100,
},
{
resolveImageFn: downloadImageToPublicDir,
},
)
},
["cms-page"],
// {
// revalidate: false,
// tags: ["cms-page"],
// },
)

const downloadImageToPublicDir = async (url: string, meta: { blockId: string; lastEditedTime: Date }) => {
const fileUrl = new URL(url)
const originalFileName = fileUrl.pathname.substring(fileUrl.pathname.lastIndexOf("/") + 1)
const newFileName = `public/cms/${meta.blockId}-${originalFileName}`

let savedLastEditedTime: Date | null = null
try {
const stat = statSync(newFileName)
savedLastEditedTime = stat.mtime
} catch (error) {
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
console.debug(`${newFileName} not found`)
} else {
console.warn(`${newFileName}: ${error}`)
}
}
// Avoid download the file again and again
if (savedLastEditedTime === null || meta.lastEditedTime > savedLastEditedTime) {
const resp = await fetch(fileUrl)
const blob = await resp.blob()
writeFileSync(newFileName, new DataView(await blob.arrayBuffer()))
console.info(`downloaded image ${newFileName} of block ${meta.blockId}`)
}

return newFileName.replace("public", nextConfig.basePath ?? "")
}
32 changes: 25 additions & 7 deletions packages/render/src/fetch.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
import { type Client, isFullBlock, iteratePaginatedAPI } from "@notionhq/client"
import { BlockObjectResponseWithChildren } from "./types"
import { type ListBlockChildrenParameters } from "@notionhq/client/build/src/api-endpoints"

export const fetchBlocksChildren = async (client: Client, blockId: string) => {
type ResolveImageFn = (url: string, meta: { blockId: string; lastEditedTime: Date }) => Promise<string>

export const fetchBlocksChildren = async (
client: Client,
firstPageArgs: ListBlockChildrenParameters,
options: { resolveImageFn?: ResolveImageFn },
) => {
const result: Array<BlockObjectResponseWithChildren> = []
for await (const block of iteratePaginatedAPI(client.blocks.children.list, {
block_id: blockId,
page_size: 100,
})) {
for await (const block of iteratePaginatedAPI(client.blocks.children.list, firstPageArgs)) {
if (isFullBlock(block)) {
if (options.resolveImageFn && block.type === "image" && block.image.type === "file") {
block.image.file.url = await options.resolveImageFn(block.image.file.url, {
blockId: block.id,
lastEditedTime: new Date(block.last_edited_time),
})
}

if (!block.has_children) {
result.push(block)
continue
Expand All @@ -19,10 +30,17 @@ export const fetchBlocksChildren = async (client: Client, blockId: string) => {

result.push({
...block,
_children: await fetchBlocksChildren(client, childId),
_children: await fetchBlocksChildren(
client,
{
...firstPageArgs,
block_id: childId,
},
options,
),
})
}
}
console.info(`fetched children from notion block ${blockId}`)
console.info(`fetched children from notion block ${firstPageArgs.block_id}`)
return result
}

0 comments on commit be6e027

Please sign in to comment.