diff --git a/apps/website/src/app/docs/packages/[packageName]/[version]/[[...item]]/page.tsx b/apps/website/src/app/docs/packages/[packageName]/[version]/[[...item]]/page.tsx index 25f8af8d7..c84669862 100644 --- a/apps/website/src/app/docs/packages/[packageName]/[version]/[[...item]]/page.tsx +++ b/apps/website/src/app/docs/packages/[packageName]/[version]/[[...item]]/page.tsx @@ -2,6 +2,7 @@ import { readFile } from 'node:fs/promises'; import { join } from 'node:path'; import rehypeShikiFromHighlighter from '@shikijs/rehype/core'; import type { Metadata } from 'next'; +import { notFound } from 'next/navigation'; import { MDXRemote } from 'next-mdx-remote-client/rsc'; import remarkGfm from 'remark-gfm'; import { DocItem } from '@/components/DocItem'; @@ -89,6 +90,7 @@ export default async function Page({ } const entryPointString = parsedEntrypoints.join('.'); + const node = await fetchNode({ entryPoint: entryPointString, item: decodeURIComponent(foundItem), @@ -96,6 +98,10 @@ export default async function Page({ version, }); + if (!node) { + notFound(); + } + return (
diff --git a/apps/website/src/middleware.ts b/apps/website/src/middleware.ts index 92359ea0a..7d2b2d89f 100644 --- a/apps/website/src/middleware.ts +++ b/apps/website/src/middleware.ts @@ -1,35 +1,6 @@ -import Cloudflare from 'cloudflare'; import { NextResponse, type NextRequest } from 'next/server'; -import { DEFAULT_ENTRY_POINT, PACKAGES, PACKAGES_WITH_ENTRY_POINTS } from './util/constants'; -import { ENV } from './util/env'; - -const client = new Cloudflare({ - apiToken: process.env.CF_D1_DOCS_API_KEY, -}); - -async function fetchLatestVersion(packageName: string): Promise { - const hasEntryPoints = PACKAGES_WITH_ENTRY_POINTS.includes(packageName); - - if (ENV.IS_LOCAL_DEV) { - if (hasEntryPoints) { - return ['main', ...DEFAULT_ENTRY_POINT].join('/'); - } - - return 'main'; - } - - try { - const { result } = await client.d1.database.query(process.env.CF_D1_DOCS_ID!, { - account_id: process.env.CF_ACCOUNT_ID!, - sql: `select version from documentation where name = ? and version != 'main' order by version desc limit 1;`, - params: [packageName], - }); - - return `${(result[0]?.results as { version: string }[] | undefined)?.[0]?.version ?? 'main'}${hasEntryPoints ? ['', ...DEFAULT_ENTRY_POINT].join('/') : ''}`; - } catch { - return ''; - } -} +import { PACKAGES } from '@/util/constants'; +import { fetchLatestVersion } from '@/util/fetchLatestVersion'; export default async function middleware(request: NextRequest) { if (request.nextUrl.pathname === '/docs') { diff --git a/apps/website/src/util/fetchEntryPoints.ts b/apps/website/src/util/fetchEntryPoints.ts index 98216b411..3a339f94b 100644 --- a/apps/website/src/util/fetchEntryPoints.ts +++ b/apps/website/src/util/fetchEntryPoints.ts @@ -11,15 +11,19 @@ export async function fetchEntryPoints(packageName: string, version: string) { } if (ENV.IS_LOCAL_DEV) { - const fileContent = await readFile( - join( - process.cwd(), - `${hasEntryPoint ? `../../../discord-api-types` : `../../packages/${packageName}`}/docs/${packageName}/split/${version}.entrypoints.api.json`, - ), - 'utf8', - ); + try { + const fileContent = await readFile( + join( + process.cwd(), + `${hasEntryPoint ? `../../../discord-api-types` : `../../packages/${packageName}`}/docs/${packageName}/split/${version}.entrypoints.api.json`, + ), + 'utf8', + ); - return JSON.parse(fileContent); + return JSON.parse(fileContent); + } catch { + return null; + } } const isMain = version === 'main'; diff --git a/apps/website/src/util/fetchLatestVersion.ts b/apps/website/src/util/fetchLatestVersion.ts new file mode 100644 index 000000000..62303ee5b --- /dev/null +++ b/apps/website/src/util/fetchLatestVersion.ts @@ -0,0 +1,31 @@ +import { Cloudflare } from 'cloudflare'; +import { PACKAGES_WITH_ENTRY_POINTS, DEFAULT_ENTRY_POINT } from '@/util/constants'; +import { ENV } from '@/util/env'; + +const client = new Cloudflare({ + apiToken: process.env.CF_D1_DOCS_API_KEY, +}); + +export async function fetchLatestVersion(packageName: string): Promise { + const hasEntryPoints = PACKAGES_WITH_ENTRY_POINTS.includes(packageName); + + if (ENV.IS_LOCAL_DEV) { + if (hasEntryPoints) { + return ['main', ...DEFAULT_ENTRY_POINT].join('/'); + } + + return 'main'; + } + + try { + const { result } = await client.d1.database.query(process.env.CF_D1_DOCS_ID!, { + account_id: process.env.CF_ACCOUNT_ID!, + sql: `select version from documentation where name = ? and version != 'main' order by version desc limit 1;`, + params: [packageName], + }); + + return `${(result[0]?.results as { version: string }[] | undefined)?.[0]?.version ?? 'main'}${hasEntryPoints ? ['', ...DEFAULT_ENTRY_POINT].join('/') : ''}`; + } catch { + return ''; + } +} diff --git a/apps/website/src/util/fetchNode.ts b/apps/website/src/util/fetchNode.ts index 8a09da835..2182ed962 100644 --- a/apps/website/src/util/fetchNode.ts +++ b/apps/website/src/util/fetchNode.ts @@ -19,15 +19,19 @@ export async function fetchNode({ const normalizeItem = item.replaceAll(':', '.').toLowerCase(); if (ENV.IS_LOCAL_DEV) { - const fileContent = await readFile( - join( - process.cwd(), - `${hasEntryPoint || normalizedEntryPoint ? `../../../discord-api-types` : `../../packages/${packageName}`}/docs/${packageName}/split/${version}.${normalizedEntryPoint}${normalizeItem}.api.json`, - ), - 'utf8', - ); + try { + const fileContent = await readFile( + join( + process.cwd(), + `${hasEntryPoint || normalizedEntryPoint ? `../../../discord-api-types` : `../../packages/${packageName}`}/docs/${packageName}/split/${version}.${normalizedEntryPoint}${normalizeItem}.api.json`, + ), + 'utf8', + ); - return JSON.parse(fileContent); + return JSON.parse(fileContent); + } catch { + return null; + } } const isMain = version === 'main'; diff --git a/apps/website/src/util/fetchSitemap.ts b/apps/website/src/util/fetchSitemap.ts index f908ba4b3..454397f7b 100644 --- a/apps/website/src/util/fetchSitemap.ts +++ b/apps/website/src/util/fetchSitemap.ts @@ -16,15 +16,19 @@ export async function fetchSitemap({ const normalizedEntryPoint = entryPoint ? `${entryPoint}.` : ''; if (ENV.IS_LOCAL_DEV) { - const fileContent = await readFile( - join( - process.cwd(), - `${hasEntryPoint || normalizedEntryPoint ? `../../../discord-api-types` : `../../packages/${packageName}`}/docs/${packageName}/split/${version}.${normalizedEntryPoint}sitemap.api.json`, - ), - 'utf8', - ); + try { + const fileContent = await readFile( + join( + process.cwd(), + `${hasEntryPoint || normalizedEntryPoint ? `../../../discord-api-types` : `../../packages/${packageName}`}/docs/${packageName}/split/${version}.${normalizedEntryPoint}sitemap.api.json`, + ), + 'utf8', + ); - return JSON.parse(fileContent); + return JSON.parse(fileContent); + } catch { + return null; + } } const isMain = version === 'main';