diff --git a/packages/notion-utils/src/get-page-table-of-contents.ts b/packages/notion-utils/src/get-page-table-of-contents.ts index ebc7a4725..e6d2dab73 100644 --- a/packages/notion-utils/src/get-page-table-of-contents.ts +++ b/packages/notion-utils/src/get-page-table-of-contents.ts @@ -15,6 +15,45 @@ const indentLevels = { sub_sub_header: 2 } +/** + * Recursive function to traverse blocks and build the table of contents. + */ +const traverseBlocks = ( + blockIds: string[], + recordMap: types.ExtendedRecordMap +): Array => { + const toc: Array = [] + + for (const blockId of blockIds) { + const block = recordMap.block[blockId]?.value + + if (block) { + const { type } = block + + if ( + type === 'header' || + type === 'sub_header' || + type === 'sub_sub_header' + ) { + toc.push({ + id: blockId, + type, + text: getTextContent(block.properties?.title), + indentLevel: indentLevels[type] + }) + } + + // If the block has content, recursively traverse it + if (block.content) { + const nestedHeaders = traverseBlocks(block.content, recordMap) + toc.push(...nestedHeaders) + } + } + } + + return toc +} + /** * Gets the metadata for a table of contents block by parsing the page's * H1, H2, and H3 elements. @@ -23,30 +62,7 @@ export const getPageTableOfContents = ( page: types.PageBlock, recordMap: types.ExtendedRecordMap ): Array => { - const toc = (page.content ?? []) - .map((blockId: string) => { - const block = recordMap.block[blockId]?.value - - if (block) { - const { type } = block - - if ( - type === 'header' || - type === 'sub_header' || - type === 'sub_sub_header' - ) { - return { - id: blockId, - type, - text: getTextContent(block.properties?.title), - indentLevel: indentLevels[type] - } - } - } - - return null - }) - .filter(Boolean) as Array + const toc = traverseBlocks(page.content ?? [], recordMap) const indentLevelStack = [ { diff --git a/yarn.lock b/yarn.lock index ff820bf54..42639e433 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9602,11 +9602,6 @@ normalize-url@^7.0.3: resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-7.0.3.tgz" integrity sha512-RiCOdwdPnzvwcBFJE4iI1ss3dMVRIrEzFpn8ftje6iBfzBInqlnRrNhxcLwBEKjPPXQKzm1Ptlxtaiv9wdcj5w== -notion-types@^6.15.6: - version "6.15.6" - resolved "https://registry.yarnpkg.com/notion-types/-/notion-types-6.15.6.tgz#eabbb28e1c514f421f0ffbf06ecdecd90e8ec8e3" - integrity sha512-JgLWDN4oHg/1sNdHDCeKUfdPl1AYsjOTnYkq+Zn7vITPykxbhw7nIxbAJ7owWUTro1cYTPh+GVmdX0mPiZGujg== - npm-bundled@^1.1.1: version "1.1.2" resolved "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz"