import { Fetch } from "./Fetch"; import { BlockFactory } from "./Notion/Blocks/Black.factory"; import { IBlock } from "./Notion/Blocks/Block.interface"; import { Page } from "./Notion/Page"; import { IPage } from "./Notion/Page.interface"; function isError(value: any): value is ErrorType { return value.is_error } function iblockLinkerPrevToNext(typedBlocks:IBlock[]) { typedBlocks.forEach((subBlockItem, itemIndex:number) => { if (itemIndex > 0 && itemIndex <= typedBlocks.length) { subBlockItem.prevBlock = typedBlocks[itemIndex - 1] } if (itemIndex >= 0 && itemIndex < typedBlocks.length) { subBlockItem.nextBlock = typedBlocks[itemIndex + 1] } }) } export class NotionPage { static async get(pageInfo : NotionPageArg): Promise { const res:NotionPageResponseType = await Fetch.getPage(pageInfo) if (res.is_error || !res.page) { console.error('cannot fetch for page with ', pageInfo.id) return res } const page = res.page const pageBlocks = await this.getBlock(pageInfo) if (isError(pageBlocks)) { page.children = [] return new Page(page) } page.children = pageBlocks return new Page(page) } static async getBlock(blockInfo: NotionBlockArg): Promise { const blockRes:NotionBlockResponseType = await Fetch.getBlocks(blockInfo) if (blockRes.is_error || !blockRes.block) { console.error('cannot fetch for block with ', blockInfo.id) return blockRes } const blockRaw = blockRes.block const getChildBlocks = async (parentBlockId:string, startCursor?:string): Promise => { const nonDashBlockId = parentBlockId.replace(/-/g, '') const startCursorOffset = nonDashBlockId === blockInfo.id ? startCursor : undefined const res = await Fetch.getChildBlocks(blockInfo, parentBlockId, 100, startCursorOffset) if (res.is_error || !res.block) { console.error(res) return [] } const childBlock = res.block const children = await Promise.all(childBlock.results.map(async (blockItem:NotionBlockType, index: number) : Promise => { const children = blockItem.has_children ? await getChildBlocks(blockItem.id, startCursor) : [] const typedBlock = BlockFactory.transformWithType(blockItem) typedBlock.children = children.map(item => BlockFactory.transformWithType(item)) iblockLinkerPrevToNext(typedBlock.children) return typedBlock })) if (blockInfo.id === nonDashBlockId && childBlock.has_more && childBlock.next_cursor) { const nextOffsetChildrenRes = await getChildBlocks(blockInfo.id, childBlock.next_cursor) if (isError(nextOffsetChildrenRes)) { console.error(nextOffsetChildrenRes) } else { children.push(...nextOffsetChildrenRes) } } return children } if (blockRaw.has_children) { const children = await getChildBlocks(blockRaw.id) iblockLinkerPrevToNext(children) return children } return [] } }