72 lines
1.7 KiB
TypeScript
72 lines
1.7 KiB
TypeScript
|
import notion from '../client'
|
||
|
import { collectPaginatedAPI, isFullBlock } from '@notionhq/client'
|
||
|
import {
|
||
|
BlockObjectResponse,
|
||
|
ListBlockChildrenParameters,
|
||
|
} from '@notionhq/client/build/src/api-endpoints'
|
||
|
import { cache } from 'react'
|
||
|
|
||
|
type Index = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10
|
||
|
type Iterate<I extends Index = 0> = I extends 0
|
||
|
? 1
|
||
|
: I extends 1
|
||
|
? 2
|
||
|
: I extends 2
|
||
|
? 3
|
||
|
: I extends 3
|
||
|
? 4
|
||
|
: I extends 4
|
||
|
? 5
|
||
|
: I extends 5
|
||
|
? 6
|
||
|
: I extends 6
|
||
|
? 7
|
||
|
: I extends 7
|
||
|
? 8
|
||
|
: I extends 8
|
||
|
? 9
|
||
|
: I extends 9
|
||
|
? 10
|
||
|
: I extends 10
|
||
|
? 10
|
||
|
: 10
|
||
|
|
||
|
export type BlockWithRecursiveChildren<I extends Index = 0> =
|
||
|
Iterate<I> extends 10
|
||
|
? BlockObjectResponse
|
||
|
: BlockObjectResponse & {
|
||
|
children?: BlockWithRecursiveChildren<Iterate<I>>[]
|
||
|
}
|
||
|
|
||
|
const getBlockRecursively = cache(
|
||
|
(blockId: string): Promise<BlockWithRecursiveChildren[]> => {
|
||
|
return collectPaginatedAPI(
|
||
|
async (args: ListBlockChildrenParameters) => {
|
||
|
const { results, ...rest } = await notion.blocks.children.list(args)
|
||
|
const recursiveChildren = await Promise.all(
|
||
|
results.map(async (block) => {
|
||
|
if (isFullBlock(block)) {
|
||
|
return block.has_children
|
||
|
? {
|
||
|
...block,
|
||
|
children: await getBlockRecursively(block.id),
|
||
|
}
|
||
|
: block
|
||
|
} else {
|
||
|
const error = `Notion API error: couldn't fetch block ${block.id}`
|
||
|
console.error(error)
|
||
|
throw new Error(error)
|
||
|
}
|
||
|
}),
|
||
|
)
|
||
|
return { results: recursiveChildren, ...rest }
|
||
|
},
|
||
|
{
|
||
|
block_id: blockId,
|
||
|
},
|
||
|
)
|
||
|
},
|
||
|
)
|
||
|
|
||
|
export default getBlockRecursively
|