diff --git a/src/app/.gitbook/image/route.ts b/src/app/.gitbook/image/route.ts
index f960fa791..3b198eba4 100644
--- a/src/app/.gitbook/image/route.ts
+++ b/src/app/.gitbook/image/route.ts
@@ -30,7 +30,7 @@ export async function GET(request: NextRequest) {
// Cloudflare-specific options are in the cf object.
const options: CloudflareImageOptions = {
fit: 'scale-down',
- format: 'auto',
+ format: 'jpeg',
quality: 100,
};
@@ -60,8 +60,6 @@ export async function GET(request: NextRequest) {
options.format = 'avif';
} else if (accept && /image\/webp/.test(accept)) {
options.format = 'webp';
- } else {
- options.format = 'jpeg';
}
try {
diff --git a/src/app/[spaceId]/.gitbook/icon/route.tsx b/src/app/[spaceId]/.gitbook/icon/route.tsx
index d0c42cd04..36961d7f6 100644
--- a/src/app/[spaceId]/.gitbook/icon/route.tsx
+++ b/src/app/[spaceId]/.gitbook/icon/route.tsx
@@ -78,7 +78,7 @@ function getOptions(inputUrl: string): {
theme: 'light' | 'dark';
} {
const url = new URL(inputUrl);
- const sizeParam = url.searchParams.get('size') ?? 'small';
+ const sizeParam = (url.searchParams.get('size') ?? 'small') as keyof typeof SIZES;
const themeParam = url.searchParams.get('theme') ?? 'light';
if (!SIZES[sizeParam] || !['light', 'dark'].includes(themeParam)) {
diff --git a/src/app/[spaceId]/.gitbook/ogimage/[pageId]/route.tsx b/src/app/[spaceId]/.gitbook/ogimage/[pageId]/route.tsx
index bb9832374..709def61b 100644
--- a/src/app/[spaceId]/.gitbook/ogimage/[pageId]/route.tsx
+++ b/src/app/[spaceId]/.gitbook/ogimage/[pageId]/route.tsx
@@ -11,7 +11,7 @@ export const runtime = 'edge';
*/
export async function GET(req: NextRequest, { params }: { params: PageIdParams }) {
const { space, page, customization } = await fetchPageData(params);
- const url = new URL(space.urls.published);
+ const url = new URL(space.urls.published ?? space.urls.app);
if (customization.socialPreview.url) {
// If user configured a custom social preview, we redirect to it.
diff --git a/src/app/[spaceId]/.gitbook/pdf/page.tsx b/src/app/[spaceId]/.gitbook/pdf/page.tsx
index 6cb8f344e..5b6516129 100644
--- a/src/app/[spaceId]/.gitbook/pdf/page.tsx
+++ b/src/app/[spaceId]/.gitbook/pdf/page.tsx
@@ -1,6 +1,6 @@
import * as React from 'react';
-import { getDocument, getSpace, getCurrentRevision } from '@/lib/api';
+import { getDocument, getSpace, getRevisionPages, ContentPointer } from '@/lib/api';
import { resolvePageId } from '@/lib/pages';
import { pagePDFContainerId, PageHrefContext } from '@/lib/links';
import { DocumentView } from '@/components/DocumentView';
@@ -8,6 +8,7 @@ import { DocumentView } from '@/components/DocumentView';
import { SpaceParams } from '../../fetch';
import { Revision, RevisionPageDocument, RevisionPageGroup, Space } from '@gitbook/api';
import { notFound } from 'next/navigation';
+import { ContentRefContext } from '@/lib/references';
export const runtime = 'edge';
@@ -29,9 +30,16 @@ export default async function PDFHTMLOutput(props: {
const { params, searchParams } = props;
const { spaceId } = params;
- const [space, revision] = await Promise.all([getSpace(spaceId), getCurrentRevision(spaceId)]);
+ const contentPointer: ContentPointer = {
+ spaceId,
+ };
- const pages = selectPages(revision, searchParams).slice(0, 4); // TODO: remove slice
+ const [space, rootPages] = await Promise.all([
+ getSpace(spaceId),
+ getRevisionPages(contentPointer),
+ ]);
+
+ const pages = selectPages(rootPages, searchParams).slice(0, 4); // TODO: remove slice
const linksContext: PageHrefContext = {
pdf: pages.map(({ page }) => page.id),
@@ -41,14 +49,19 @@ export default async function PDFHTMLOutput(props: {
<>
{pages.map(({ page, depth }) =>
page.type === 'group' ? (
-
+
) : (
),
)}
@@ -56,7 +69,7 @@ export default async function PDFHTMLOutput(props: {
);
}
-async function PDFPageGroup(props: { space: Space; revision: Revision; page: RevisionPageGroup }) {
+async function PDFPageGroup(props: { space: Space; page: RevisionPageGroup }) {
const { page } = props;
return (
@@ -68,30 +81,18 @@ async function PDFPageGroup(props: { space: Space; revision: Revision; page: Rev
async function PDFPageDocument(props: {
space: Space;
- revision: Revision;
page: RevisionPageDocument;
- linksContext: PageHrefContext;
+ refContext: ContentRefContext;
}) {
- const { space, revision, page, linksContext } = props;
+ const { space, page, refContext } = props;
- const document = page.documentId
- ? await getDocument(space.id, revision.id, page.documentId)
- : null;
+ const document = page.documentId ? await getDocument(space.id, page.documentId) : null;
return (
{page.title}
{document ? (
-
+
) : null}
);
@@ -102,7 +103,7 @@ type FlatPageEntry = { page: RevisionPageDocument | RevisionPageGroup; depth: nu
/**
* Compute the ordered flat set of pages to render.
*/
-function selectPages(revision: Revision, params: PDFSearchParams): FlatPageEntry[] {
+function selectPages(rootPages: Revision['pages'], params: PDFSearchParams): FlatPageEntry[] {
const flattenPage = (
page: RevisionPageDocument | RevisionPageGroup,
depth: number,
@@ -116,8 +117,8 @@ function selectPages(revision: Revision, params: PDFSearchParams): FlatPageEntry
};
if (params.page) {
- const found = resolvePageId(revision, params.page);
- if (!found || found.page.type === 'link') {
+ const found = resolvePageId(rootPages, params.page);
+ if (!found) {
notFound();
}
@@ -128,5 +129,5 @@ function selectPages(revision: Revision, params: PDFSearchParams): FlatPageEntry
return flattenPage(found.page, 0);
}
- return revision.pages.flatMap((page) => (page.type === 'link' ? [] : flattenPage(page, 0)));
+ return rootPages.flatMap((page) => (page.type === 'link' ? [] : flattenPage(page, 0)));
}
diff --git a/src/components/state/useIsLoadingPage.tsx b/src/components/state/useIsLoadingPage.tsx
index ef1688111..79f6b1893 100644
--- a/src/components/state/useIsLoadingPage.tsx
+++ b/src/components/state/useIsLoadingPage.tsx
@@ -5,17 +5,20 @@ const loadingPageAtom = atom({
default: false,
effects: [
({ setSelf }) => {
+ // @ts-ignore
if (typeof window === 'undefined' || !window.navigation) {
return;
}
+ // @ts-ignore
window.navigation.addEventListener('navigate', () => {
// Next.js finished fetching the page and update the URL.
setSelf(false);
});
document.addEventListener('click', (event) => {
- if (event.target.tagName !== 'A') {
+ // @ts-ignore
+ if (!event.target || event.target.tagName !== 'A') {
return;
}
diff --git a/src/lib/api.ts b/src/lib/api.ts
index 9e158706b..c211fdc10 100644
--- a/src/lib/api.ts
+++ b/src/lib/api.ts
@@ -230,7 +230,7 @@ export const getRevisionPageByPath = cache(
],
});
} catch (error) {
- if (error.code === 404) {
+ if ((error as GitBookAPIError).code === 404) {
return {
data: null,
tags: [
@@ -297,22 +297,6 @@ export const getRevisionFile = cache(
},
);
-/**
- * Get the current revision of a space
- */
-export const getCurrentRevision = cache('api.getCurrentRevision', async (spaceId: string) => {
- const response = await api().spaces.getCurrentRevision(spaceId, {
- ...noCacheFetchOptions,
- });
- return cacheResponse(response, {
- tags: [
- getAPICacheTag({ tag: 'space', space: spaceId }),
- getAPICacheTag({ tag: 'space-pages', space: spaceId }),
- getAPICacheTag({ tag: 'space-files', space: spaceId }),
- ],
- });
-});
-
/**
* Get a document by its ID.
*/
diff --git a/src/lib/images.ts b/src/lib/images.ts
index 764eb125a..dc8ca9dba 100644
--- a/src/lib/images.ts
+++ b/src/lib/images.ts
@@ -17,7 +17,7 @@ export interface CloudflareImageJsonFormat {
* https://developers.cloudflare.com/images/image-resizing/resize-with-workers/
*/
export interface CloudflareImageOptions {
- format?: 'webp' | 'avif' | 'json';
+ format?: 'webp' | 'avif' | 'json' | 'jpeg';
fit?: 'scale-down' | 'contain' | 'cover' | 'fill' | 'inside' | 'outside';
width?: number;
height?: number;
diff --git a/tsconfig.json b/tsconfig.json
index 4b59dfa05..72f9b87d1 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -25,6 +25,13 @@
"bun-types" // add Bun global
]
},
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
+ "include": [
+ "next-env.d.ts",
+ "**/*.ts",
+ "**/*.tsx",
+ "**/.gitbook/**/*.ts",
+ "**/.gitbook/**/*.tsx",
+ ".next/types/**/*.ts"
+ ],
"exclude": ["node_modules"]
}