diff --git a/bun.lockb b/bun.lockb index 4c7450de7..d69839a2a 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 77dc987ab..2b7cc8a59 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ }, "dependencies": { "@geist-ui/icons": "^1.0.2", - "@gitbook/api": "^0.15.0", + "@gitbook/api": "^0.16.0", "@readme/openapi-parser": "^2.5.0", "@upstash/redis": "^1.25.1", "ajv": "^8.12.0", diff --git a/src/app/[spaceId]/[[...pathname]]/layout.tsx b/src/app/[spaceId]/[[...pathname]]/layout.tsx index f1809487e..c24c9cafe 100644 --- a/src/app/[spaceId]/[[...pathname]]/layout.tsx +++ b/src/app/[spaceId]/[[...pathname]]/layout.tsx @@ -5,10 +5,11 @@ import shadesOf from 'tailwind-shades'; import colors from 'tailwindcss/colors'; import { hexToRgb } from '@/components/utils/HexToRgb'; +import { getSpaceCustomization } from '@/lib/api'; import { tcls } from '@/lib/tailwind'; import { ClientLayout } from './ClientLayout'; -import { PagePathParams, fetchPageData } from '../fetch'; +import { PagePathParams } from '../fetch'; const inter = Inter({ subsets: ['latin'] }); @@ -16,8 +17,9 @@ export default async function SpaceRootLayout(props: { children: React.ReactNode; params: PagePathParams; }) { - const { children, params } = props; - const { customization } = await fetchPageData(params); + const { params, children } = props; + + const customization = await getSpaceCustomization(params.spaceId); const headerTheme = generateHeaderTheme(customization); return ( diff --git a/src/app/[spaceId]/[[...pathname]]/page.tsx b/src/app/[spaceId]/[[...pathname]]/page.tsx index aa957b49d..2db10d8cf 100644 --- a/src/app/[spaceId]/[[...pathname]]/page.tsx +++ b/src/app/[spaceId]/[[...pathname]]/page.tsx @@ -17,7 +17,7 @@ export const runtime = 'nodejs'; export default async function Page(props: { params: PagePathParams }) { const { params } = props; - const { space, customization, revision, page, collection, collectionSpaces, ancestors } = + const { content, space, customization, pages, page, collection, collectionSpaces, ancestors } = await fetchPageData(params); const linksContext: PageHrefContext = {}; @@ -27,13 +27,14 @@ export default async function Page(props: { params: PagePathParams }) { redirect(pageHref(page, linksContext)); } - const document = await getPageDocument(space.id, revision.id, page.id); + const document = await getPageDocument(content, page.id); return ( { // Decay priority with depth const priority = Math.pow(2, -0.25 * depth); @@ -70,7 +67,7 @@ export async function GET(req: NextRequest, { params }: { params: SpaceParams }) type FlatPageEntry = { page: RevisionPageDocument; depth: number }; -function flattenPages(revision: Revision): FlatPageEntry[] { +function flattenPages(rootPags: RevisionPage[]): FlatPageEntry[] { const flattenPage = ( page: RevisionPageDocument | RevisionPageGroup, depth: number, @@ -83,5 +80,5 @@ function flattenPages(revision: Revision): FlatPageEntry[] { ]; }; - return revision.pages.flatMap((page) => (page.type === 'link' ? [] : flattenPage(page, 0))); + return rootPags.flatMap((page) => (page.type === 'link' ? [] : flattenPage(page, 0))); } diff --git a/src/components/DocumentView/File.tsx b/src/components/DocumentView/File.tsx index be5e69100..e715840b9 100644 --- a/src/components/DocumentView/File.tsx +++ b/src/components/DocumentView/File.tsx @@ -1,14 +1,15 @@ import IconDownload from '@geist-ui/icons/download'; import { DocumentBlockFile } from '@gitbook/api'; +import { getRevisionFile } from '@/lib/api'; import { tcls } from '@/lib/tailwind'; import { BlockProps } from './Block'; -export function File(props: BlockProps) { +export async function File(props: BlockProps) { const { block, context, style } = props; - const file = context.revision.files.find((f) => f.id === block.data.ref.file); + const file = await getRevisionFile(context.content, block.data.ref.file); if (!file) { return null; } diff --git a/src/components/Footer/Footer.tsx b/src/components/Footer/Footer.tsx index 76ede9046..9c2b04a6d 100644 --- a/src/components/Footer/Footer.tsx +++ b/src/components/Footer/Footer.tsx @@ -2,6 +2,7 @@ import { CustomizationSettings, Revision, RevisionPageDocument, Space } from '@g import React from 'react'; import { Image } from '@/components/utils'; +import { ContentRefContext } from '@/lib/references'; import { tcls } from '@/lib/tailwind'; import { FooterLinksGroup } from './FooterLinksGroup'; @@ -10,12 +11,11 @@ import { ThemeToggler } from '../ThemeToggler'; export function Footer(props: { space: Space; - revision: Revision; - page: RevisionPageDocument; + context: ContentRefContext; customization: CustomizationSettings; asFullWidth: boolean; }) { - const { space, revision, page, customization, asFullWidth } = props; + const { space, context, customization, asFullWidth } = props; return (
( - + ))}
) : null} diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index 9a3ecfb44..d44d124ec 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -1,14 +1,9 @@ -import { - Collection, - CustomizationSettings, - Revision, - RevisionPageDocument, - Space, -} from '@gitbook/api'; +import { Collection, CustomizationSettings, Space } from '@gitbook/api'; import { Suspense } from 'react'; import { CONTAINER_MAX_WIDTH_NORMAL, CONTAINER_PADDING } from '@/components/layout'; import { t } from '@/lib/intl'; +import { ContentRefContext } from '@/lib/references'; import { tcls } from '@/lib/tailwind'; import { CollectionSpacesDropdown } from './CollectionSpacesDropdown'; @@ -23,13 +18,11 @@ export function Header(props: { space: Space; collection: Collection | null; collectionSpaces: Space[]; - revision: Revision; - page: RevisionPageDocument; + context: ContentRefContext; asFullWidth: boolean; customization: CustomizationSettings; }) { - const { space, collection, collectionSpaces, revision, page, asFullWidth, customization } = - props; + const { context, space, collection, collectionSpaces, asFullWidth, customization } = props; return (
{customization.header.links.map((link, index) => ( - + ))}
diff --git a/src/components/Header/HeaderLink.tsx b/src/components/Header/HeaderLink.tsx index c54aa41c6..c4e208eab 100644 --- a/src/components/Header/HeaderLink.tsx +++ b/src/components/Header/HeaderLink.tsx @@ -1,13 +1,7 @@ -import { - CustomizationContentLink, - CustomizationHeaderLink, - Revision, - RevisionPageDocument, - Space, -} from '@gitbook/api'; +import { CustomizationContentLink, CustomizationHeaderLink } from '@gitbook/api'; import Link from 'next/link'; -import { resolveContentRef } from '@/lib/references'; +import { ContentRefContext, resolveContentRef } from '@/lib/references'; import { tcls } from '@/lib/tailwind'; import { @@ -19,18 +13,12 @@ import { } from './Dropdown'; export async function HeaderLink(props: { - space: Space; - revision: Revision; - page: RevisionPageDocument; + context: ContentRefContext; link: CustomizationHeaderLink; }) { - const { space, revision, page, link } = props; + const { context, link } = props; - const target = await resolveContentRef(link.to, { - space, - revision, - page, - }); + const target = await resolveContentRef(link.to, context); if (!target) { return null; @@ -73,18 +61,12 @@ export async function HeaderLink(props: { } async function SubHeaderLink(props: { - space: Space; - revision: Revision; - page: RevisionPageDocument; + context: ContentRefContext; link: CustomizationContentLink; }) { - const { space, revision, page, link } = props; + const { context, link } = props; - const target = await resolveContentRef(link.to, { - space, - revision, - page, - }); + const target = await resolveContentRef(link.to, context); if (!target) { return null; diff --git a/src/components/PageBody/PageBody.tsx b/src/components/PageBody/PageBody.tsx index 740ccab7e..528dce299 100644 --- a/src/components/PageBody/PageBody.tsx +++ b/src/components/PageBody/PageBody.tsx @@ -1,5 +1,6 @@ -import { Revision, RevisionPageDocument, Space } from '@gitbook/api'; +import { JSONDocument, Revision, RevisionPageDocument, Space } from '@gitbook/api'; +import { ContentRefContext } from '@/lib/references'; import { tcls } from '@/lib/tailwind'; import { PageFooterNavigation } from './PageFooterNavigation'; @@ -8,25 +9,17 @@ import { DocumentView } from '../DocumentView'; export function PageBody(props: { space: Space; - revision: Revision; page: RevisionPageDocument; - document: any; + context: ContentRefContext; + document: JSONDocument; }) { - const { space, revision, page, document } = props; + const { space, context, page, document } = props; return (
- - + +
); } diff --git a/src/components/PageBody/PageFooterNavigation.tsx b/src/components/PageBody/PageFooterNavigation.tsx index 75a5a1930..2c53a7403 100644 --- a/src/components/PageBody/PageFooterNavigation.tsx +++ b/src/components/PageBody/PageFooterNavigation.tsx @@ -13,11 +13,11 @@ import { tcls } from '@/lib/tailwind'; */ export function PageFooterNavigation(props: { space: Space; - revision: Revision; + pages: Revision['pages']; page: RevisionPageDocument; }) { - const { space, revision, page } = props; - const { previous, next } = resolvePrevNextPages(revision, page); + const { space, pages, page } = props; + const { previous, next } = resolvePrevNextPages(pages, page); return (
diff --git a/src/components/SpaceContent/SpaceContent.tsx b/src/components/SpaceContent/SpaceContent.tsx index f4533d10f..7b1a4f4c9 100644 --- a/src/components/SpaceContent/SpaceContent.tsx +++ b/src/components/SpaceContent/SpaceContent.tsx @@ -15,8 +15,10 @@ import { CONTAINER_MAX_WIDTH_NORMAL, CONTAINER_PADDING } from '@/components/layo import { PageBody } from '@/components/PageBody'; import { SearchModal } from '@/components/Search'; import { TableOfContents } from '@/components/TableOfContents'; +import { ContentPointer } from '@/lib/api'; import { hasFullWidthBlock } from '@/lib/document'; import { tString } from '@/lib/intl'; +import { ContentRefContext } from '@/lib/references'; import { tcls } from '@/lib/tailwind'; import { PageAside } from '../PageAside'; @@ -25,11 +27,12 @@ import { PageAside } from '../PageAside'; * Render the entire content of the space (header, table of contents, footer, and page content). */ export function SpaceContent(props: { + content: ContentPointer; space: Space; collection: Collection | null; collectionSpaces: Space[]; customization: CustomizationSettings; - revision: Revision; + pages: Revision['pages']; page: RevisionPageDocument; ancestors: Array; document: any; @@ -38,7 +41,8 @@ export function SpaceContent(props: { space, collection, collectionSpaces, - revision, + content, + pages, customization, page, ancestors, @@ -48,6 +52,13 @@ export function SpaceContent(props: { const asFullWidth = hasFullWidthBlock(document); const withTopHeader = customization.header.preset !== CustomizationHeaderPreset.None; + const contentRefContext: ContentRefContext = { + space, + pages, + page, + content, + }; + return (
{withTopHeader ? ( @@ -55,8 +66,7 @@ export function SpaceContent(props: { space={space} collection={collection} collectionSpaces={collectionSpaces} - revision={revision} - page={page} + context={contentRefContext} customization={customization} asFullWidth={asFullWidth} /> @@ -72,9 +82,11 @@ export function SpaceContent(props: { > - + diff --git a/src/components/TableOfContents/PageDocumentItem.tsx b/src/components/TableOfContents/PageDocumentItem.tsx index 377ef76c4..92646b448 100644 --- a/src/components/TableOfContents/PageDocumentItem.tsx +++ b/src/components/TableOfContents/PageDocumentItem.tsx @@ -2,6 +2,7 @@ import { RevisionPageDocument, RevisionPageGroup } from '@gitbook/api'; import Link from 'next/link'; import { pageHref } from '@/lib/links'; +import { ContentRefContext } from '@/lib/references'; import { tcls } from '@/lib/tailwind'; import { PagesList } from './PagesList'; @@ -11,8 +12,9 @@ export function PageDocumentItem(props: { page: RevisionPageDocument; activePage: RevisionPageDocument; ancestors: Array; + context: ContentRefContext; }) { - const { page, activePage, ancestors } = props; + const { page, activePage, ancestors, context } = props; const hasActiveDescendant = ancestors.some((ancestor) => ancestor.id === page.id); @@ -64,6 +66,7 @@ export function PageDocumentItem(props: { )} activePage={activePage} ancestors={ancestors} + context={context} /> } defaultOpen={hasActiveDescendant || activePage.id === page.id} diff --git a/src/components/TableOfContents/PageGroupItem.tsx b/src/components/TableOfContents/PageGroupItem.tsx index debc8698d..c5210a879 100644 --- a/src/components/TableOfContents/PageGroupItem.tsx +++ b/src/components/TableOfContents/PageGroupItem.tsx @@ -1,5 +1,6 @@ import { RevisionPageDocument, RevisionPageGroup } from '@gitbook/api'; +import { ContentRefContext } from '@/lib/references'; import { tcls } from '@/lib/tailwind'; import { PagesList } from './PagesList'; @@ -8,14 +9,20 @@ export function PageGroupItem(props: { page: RevisionPageGroup; activePage: RevisionPageDocument; ancestors: Array; + context: ContentRefContext; }) { - const { page, activePage, ancestors } = props; + const { page, activePage, ancestors, context } = props; return (
  • {page.title}
    {page.pages && page.pages.length ? ( - + ) : null}
  • ); diff --git a/src/components/TableOfContents/PageLinkItem.tsx b/src/components/TableOfContents/PageLinkItem.tsx index 145c5487d..e58fecb25 100644 --- a/src/components/TableOfContents/PageLinkItem.tsx +++ b/src/components/TableOfContents/PageLinkItem.tsx @@ -1,17 +1,18 @@ import { RevisionPageLink } from '@gitbook/api'; import Link from 'next/link'; +import { ContentRefContext, resolveContentRef } from '@/lib/references'; import { tcls } from '@/lib/tailwind'; -export function PageLinkItem(props: { page: RevisionPageLink }) { - const { page } = props; +export async function PageLinkItem(props: { page: RevisionPageLink; context: ContentRefContext }) { + const { page, context } = props; + + const resolved = await resolveContentRef(page.target, context); return (
  • ; + context: ContentRefContext; style?: ClassValue; }) { - const { pages, activePage, ancestors, style } = props; + const { pages, activePage, ancestors, context, style } = props; return (
      @@ -24,10 +26,11 @@ export function PagesList(props: { page={page} activePage={activePage} ancestors={ancestors} + context={context} /> ); } else if (page.type === 'link') { - return ; + return ; } return ( @@ -36,6 +39,7 @@ export function PagesList(props: { page={page} activePage={activePage} ancestors={ancestors} + context={context} /> ); })} diff --git a/src/components/TableOfContents/TableOfContents.tsx b/src/components/TableOfContents/TableOfContents.tsx index 66c97a73c..7a9888007 100644 --- a/src/components/TableOfContents/TableOfContents.tsx +++ b/src/components/TableOfContents/TableOfContents.tsx @@ -1,7 +1,9 @@ import { Revision, RevisionPageDocument, RevisionPageGroup } from '@gitbook/api'; import React from 'react'; +import { ContentPointer } from '@/lib/api'; import { IntlContext } from '@/lib/intl'; +import { ContentRefContext } from '@/lib/references'; import { tcls } from '@/lib/tailwind'; import { PagesList } from './PagesList'; @@ -10,14 +12,24 @@ import { SIDE_COLUMN_WITHOUT_HEADER, SIDE_COLUMN_WITH_HEADER } from '../layout'; export function TableOfContents( props: IntlContext & { - revision: Revision; + content: ContentPointer; + context: ContentRefContext; + pages: Revision['pages']; activePage: RevisionPageDocument; ancestors: Array; header?: React.ReactNode; withHeaderOffset?: boolean; }, ) { - const { space, revision, activePage, ancestors, header, withHeaderOffset = false } = props; + const { + space, + pages, + activePage, + ancestors, + header, + context, + withHeaderOffset = false, + } = props; return (
  • diff --git a/src/lib/api.ts b/src/lib/api.ts index 5734343fa..1b36d6f92 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -5,6 +5,12 @@ import { headers } from 'next/headers'; import { cache } from './cache'; +export interface ContentPointer { + spaceId: string; + changeRequestId?: string; + revisionId?: string; +} + /** * Create an API client for the current request. */ @@ -36,6 +42,72 @@ export const getSpace = cache('api.getSpace', async (spaceId: string) => { return data; }); +/** + * Get all the pages in the space. + */ +export const getRevisionPages = cache('api.getRevisionPages', async (pointer: ContentPointer) => { + const { data } = await (async () => { + if (pointer.revisionId) { + return api().spaces.listPagesInRevisionById(pointer.spaceId, pointer.revisionId, { + cache: 'no-store', + }); + } + + if (pointer.changeRequestId) { + return api().spaces.listPagesInChangeRequest(spaceId, pointer.changeRequestId, { + cache: 'no-store', + }); + } + + return api().spaces.listPages(pointer.spaceId, { + cache: 'no-store', + }); + })(); + return data.pages!; +}); + +/** + * Resolve a file by its ID. + */ +export const getRevisionFile = cache( + 'api.getRevisionFile', + async (pointer: ContentPointer, fileId: string) => { + try { + const { data } = await (async () => { + if (pointer.revisionId) { + return api().spaces.getFileInRevisionById( + pointer.spaceId, + pointer.revisionId, + fileId, + { + cache: 'no-store', + }, + ); + } + + if (pointer.changeRequestId) { + return api().spaces.getFileInChangeRequestById( + spaceId, + pointer.changeRequestId, + fileId, + { + cache: 'no-store', + }, + ); + } + + return api().spaces.getFileById(pointer.spaceId, fileId, { + cache: 'no-store', + }); + })(); + return data; + } catch (error) { + // TODO: improve error handling to throw non-404 + return null; + } + }, +); + /** * Get the current revision of a space */ @@ -51,21 +123,59 @@ export const getCurrentRevision = cache('api.getCurrentRevision', async (spaceId */ export const getPageDocument = cache( 'api.getPageDocument', - async (spaceId: string, revisionId: string, pageId: string) => { - const { data } = await api().spaces.getPageInRevisionById( - spaceId, - revisionId, - pageId, - {}, - { - cache: 'no-store', - }, - ); + async (pointer: ContentPointer, pageId: string) => { + const { data } = await (async () => { + if (pointer.revisionId) { + return api().spaces.getPageInRevisionById( + pointer.spaceId, + pointer.revisionId, + pageId, + { + format: 'document', + }, + { + cache: 'no-store', + }, + ); + } + + if (pointer.changeRequestId) { + return api().spaces.getPageInChangeRequestById( + pointer.spaceId, + pointer.changeRequestId, + pageId, + { + format: 'document', + }, + { + cache: 'no-store', + }, + ); + } + + return api().spaces.getPageById( + pointer.spaceId, + pageId, + { + format: 'document', + }, + { + cache: 'no-store', + }, + ); + })(); // @ts-ignore return data.document as JSONDocument; }, ); +/** + * Get a document by its ID. + */ +export const getDocument = cache('api.getDocument', async (spaceId: string, documentId: string) => { + // TODO +}); + /** * Get the customization settings for a space. */ @@ -79,8 +189,8 @@ export const getSpaceCustomization = cache('api.getSpaceCustomization', async (s /** * Get the infos about a collection by its ID. */ -export const getCollection = cache('api.getCollection', async (spaceId: string) => { - const { data } = await api().collections.getCollectionById(spaceId, { +export const getCollection = cache('api.getCollection', async (collectionId: string) => { + const { data } = await api().collections.getCollectionById(collectionId, { cache: 'no-store', }); return data; @@ -89,14 +199,17 @@ export const getCollection = cache('api.getCollection', async (spaceId: string) /** * List all the spaces variants published in a collection. */ -export const getCollectionSpaces = cache('api.getCollectionSpaces', async (spaceId: string) => { - const { data } = await api().collections.listSpacesInCollectionById( - spaceId, - {}, - { - cache: 'no-store', - }, - ); - // TODO: do this filtering on the API side - return data.items.filter((space) => space.visibility === ContentVisibility.InCollection); -}); +export const getCollectionSpaces = cache( + 'api.getCollectionSpaces', + async (collectionId: string) => { + const { data } = await api().collections.listSpacesInCollectionById( + collectionId, + {}, + { + cache: 'no-store', + }, + ); + // TODO: do this filtering on the API side + return data.items.filter((space) => space.visibility === ContentVisibility.InCollection); + }, +); diff --git a/src/lib/cache.ts b/src/lib/cache.ts index 93778ce66..8889999b7 100644 --- a/src/lib/cache.ts +++ b/src/lib/cache.ts @@ -15,7 +15,7 @@ const memoryCache = new Map(); * Cache data from an async function. * We don't use the next.js cache because it has a 2MB limit. */ -export function cache( +export function cache( fnName: string, fn: (...args: Args) => Promise, ): (...args: Args) => Promise { @@ -38,8 +38,8 @@ export function cache( /** * Create a cache key from a function name and its arguments. */ -function getCacheKey(fnName: string, args: string[]) { - return `${fnName}(${args.join(',')})`; +function getCacheKey(fnName: string, args: any[]) { + return `${fnName}(${args.map((arg) => JSON.stringify(arg)).join(',')})`; } /** diff --git a/src/lib/pages.ts b/src/lib/pages.ts index bdaf13e35..e53db5fbc 100644 --- a/src/lib/pages.ts +++ b/src/lib/pages.ts @@ -6,7 +6,7 @@ export type AncestorRevisionPage = RevisionPageDocument | RevisionPageGroup; * Resolve a page path to a page document. */ export function resolvePagePath( - revision: Revision, + rootPages: Revision['pages'], pagePath: string, ): { page: RevisionPageDocument; ancestors: AncestorRevisionPage[] } | undefined { const iteratePages = ( @@ -33,7 +33,7 @@ export function resolvePagePath( }; if (!pagePath) { - const firstPage = resolveFirstDocument(revision.pages, []); + const firstPage = resolveFirstDocument(rootPages, []); if (!firstPage) { return undefined; } @@ -41,14 +41,14 @@ export function resolvePagePath( return firstPage; } - return iteratePages(revision.pages, []); + return iteratePages(rootPages, []); } /** * Find a page by its ID in a revision. */ export function resolvePageId( - revision: Revision, + rootPages: Revision['pages'], pageId: string, ): { page: RevisionPageDocument; ancestors: AncestorRevisionPage[] } | undefined { const iteratePages = ( @@ -70,17 +70,17 @@ export function resolvePageId( } } }; - return iteratePages(revision.pages, []); + return iteratePages(rootPages, []); } /** * Resolve the next/previous page before another one. */ export function resolvePrevNextPages( - revision: Revision, + rootPages: Revision['pages'], page: RevisionPageDocument, ): { previous?: RevisionPageDocument; next?: RevisionPageDocument } { - const flat = flattenPages(revision.pages); + const flat = flattenPages(rootPages); const currentIndex = flat.findIndex((p) => p.id === page.id); if (currentIndex === -1) { diff --git a/src/lib/references.ts b/src/lib/references.ts index 4256b2ec9..97c61e309 100644 --- a/src/lib/references.ts +++ b/src/lib/references.ts @@ -1,5 +1,6 @@ import { ContentRef, Revision, RevisionPageDocument, Space } from '@gitbook/api'; +import { ContentPointer, getRevisionFile } from './api'; import { pageHref, PageHrefContext } from './links'; import { resolvePageId } from './pages'; @@ -13,8 +14,9 @@ export interface ResolvedContentRef { } export interface ContentRefContext extends PageHrefContext { + content: ContentPointer; space: Space; - revision: Revision; + pages: Revision['pages']; page: RevisionPageDocument; } @@ -23,7 +25,7 @@ export interface ContentRefContext extends PageHrefContext { */ export async function resolveContentRef( contentRef: ContentRef, - { space, revision, page: activePage, ...linksContext }: ContentRefContext, + { content, space, pages, page: activePage, ...linksContext }: ContentRefContext, ): Promise { // Try to resolve a local ref in the current space if (contentRef.kind === 'url') { @@ -33,7 +35,7 @@ export async function resolveContentRef( active: false, }; } else if (contentRef.kind === 'file') { - const file = revision.files.find((file) => file.id === contentRef.file); + const file = await getRevisionFile(content, contentRef.file); if (file) { return { href: file.downloadURL, @@ -50,7 +52,7 @@ export async function resolveContentRef( const page = !contentRef.page || contentRef.page === activePage.id ? activePage - : resolvePageId(revision, contentRef.page)?.page; + : resolvePageId(pages, contentRef.page)?.page; if (!page) { return null; }