mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-13 18:13:29 +01:00
refactor: use planetscale instead of custom api
This commit is contained in:
@@ -72,8 +72,7 @@
|
||||
"react-use": "^17.4.0",
|
||||
"rehype-slug": "^5.1.0",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"sharp": "^0.32.6",
|
||||
"swr": "^2.2.4"
|
||||
"sharp": "^0.32.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@next/bundle-analyzer": "^14.0.1",
|
||||
|
||||
@@ -15,11 +15,12 @@ export async function fetchVersions(packageName: string): Promise<string[]> {
|
||||
return ['main'];
|
||||
}
|
||||
|
||||
const response = await fetch(`https://docs.discordjs.dev/api/info?package=${packageName}`, {
|
||||
next: { revalidate: 3_600 },
|
||||
});
|
||||
const { rows } = await sql.execute('select version from documentation where name = ? order by version desc', [
|
||||
packageName,
|
||||
]);
|
||||
|
||||
return response.json();
|
||||
// @ts-expect-error: https://github.com/planetscale/database-js/issues/71
|
||||
return rows[0].data;
|
||||
}
|
||||
|
||||
export async function fetchModelJSON(packageName: string, version: string): Promise<unknown> {
|
||||
|
||||
@@ -68,6 +68,8 @@ export default async function PackageLayout({ children, params }: PropsWithChild
|
||||
return (member as ApiFunction).overloadIndex === 1;
|
||||
});
|
||||
|
||||
const versions = await fetchVersions(params.package);
|
||||
|
||||
return (
|
||||
<Providers>
|
||||
<Banner className="mb-6" />
|
||||
@@ -75,7 +77,7 @@ export default async function PackageLayout({ children, params }: PropsWithChild
|
||||
<Header />
|
||||
<div className="relative top-2.5 mx-auto max-w-7xl gap-6 lg:max-w-full lg:flex">
|
||||
<div className="lg:sticky lg:top-23 lg:h-[calc(100vh_-_145px)]">
|
||||
<Nav members={members.map((member) => serializeIntoSidebarItemData(member))} />
|
||||
<Nav members={members.map((member) => serializeIntoSidebarItemData(member))} versions={versions} />
|
||||
</div>
|
||||
|
||||
<div className="mx-auto max-w-5xl min-w-xs w-full pb-10">
|
||||
|
||||
@@ -3,6 +3,7 @@ import { VscArrowRight } from '@react-icons/all-files/vsc/VscArrowRight';
|
||||
import { VscVersions } from '@react-icons/all-files/vsc/VscVersions';
|
||||
import Link from 'next/link';
|
||||
import { notFound } from 'next/navigation';
|
||||
import { fetchVersions } from '~/app/docAPI';
|
||||
import { buttonVariants } from '~/styles/Button';
|
||||
import { PACKAGES } from '~/util/constants';
|
||||
|
||||
@@ -11,18 +12,13 @@ async function getData(pkg: string) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
if (process.env.NEXT_PUBLIC_LOCAL_DEV || process.env.NEXT_PUBLIC_VERCEL_ENV === 'preview') {
|
||||
return ['main'];
|
||||
}
|
||||
|
||||
const res = await fetch(`https://docs.discordjs.dev/api/info?package=${pkg}`, { next: { revalidate: 3_600 } });
|
||||
const data: string[] = await res.json();
|
||||
const data = await fetchVersions(pkg);
|
||||
|
||||
if (!data.length) {
|
||||
throw new Error('Failed to fetch data');
|
||||
}
|
||||
|
||||
return data.reverse();
|
||||
return data;
|
||||
}
|
||||
|
||||
export default async function Page({ params }: { params: { package: string } }) {
|
||||
|
||||
@@ -9,7 +9,13 @@ import type { SidebarSectionItemData } from './Sidebar';
|
||||
const PackageSelect = dynamic(async () => import('./PackageSelect'));
|
||||
const VersionSelect = dynamic(async () => import('./VersionSelect'));
|
||||
|
||||
export function Nav({ members }: { readonly members: SidebarSectionItemData[] }) {
|
||||
export function Nav({
|
||||
members,
|
||||
versions,
|
||||
}: {
|
||||
readonly members: SidebarSectionItemData[];
|
||||
readonly versions: string[];
|
||||
}) {
|
||||
const { opened } = useNav();
|
||||
|
||||
return (
|
||||
@@ -30,7 +36,7 @@ export function Nav({ members }: { readonly members: SidebarSectionItemData[] })
|
||||
>
|
||||
<div className="flex flex-col gap-4 p-3">
|
||||
<PackageSelect />
|
||||
<VersionSelect />
|
||||
<VersionSelect versions={versions} />
|
||||
</div>
|
||||
<Sidebar members={members} />
|
||||
</Scrollbars>
|
||||
|
||||
@@ -6,34 +6,29 @@ import { Menu, MenuButton, MenuItem, useMenuState } from 'ariakit/menu';
|
||||
import Link from 'next/link';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { useMemo } from 'react';
|
||||
import useSWR from 'swr';
|
||||
import { fetcher } from '~/util/fetcher';
|
||||
|
||||
const isDev = process.env.NEXT_PUBLIC_LOCAL_DEV ?? process.env.NEXT_PUBLIC_VERCEL_ENV === 'preview';
|
||||
|
||||
export default function VersionSelect() {
|
||||
export default function VersionSelect({ versions }: { readonly versions: string[] }) {
|
||||
const pathname = usePathname();
|
||||
const packageName = pathname?.split('/').slice(3, 4)[0];
|
||||
const branchName = pathname?.split('/').slice(4, 5)[0];
|
||||
|
||||
const { data: versions } = useSWR<string[]>(`https://docs.discordjs.dev/api/info?package=${packageName}`, fetcher);
|
||||
const versionMenu = useMenuState({ gutter: 8, sameWidth: true, fitViewport: true });
|
||||
|
||||
const versionMenuItems = useMemo(
|
||||
() =>
|
||||
versions
|
||||
?.map((item, idx) => (
|
||||
<Link href={`/docs/packages/${packageName}/${isDev ? 'main' : item}`} key={`${item}-${idx}`}>
|
||||
<MenuItem
|
||||
className="my-0.5 rounded bg-white p-3 text-sm outline-none active:bg-light-800 dark:bg-dark-600 hover:bg-light-700 focus:ring focus:ring-width-2 focus:ring-blurple dark:active:bg-dark-400 dark:hover:bg-dark-500"
|
||||
onClick={() => versionMenu.setOpen(false)}
|
||||
state={versionMenu}
|
||||
>
|
||||
{item}
|
||||
</MenuItem>
|
||||
</Link>
|
||||
))
|
||||
.reverse() ?? [],
|
||||
versions?.map((item, idx) => (
|
||||
<Link href={`/docs/packages/${packageName}/${isDev ? 'main' : item}`} key={`${item}-${idx}`}>
|
||||
<MenuItem
|
||||
className="my-0.5 rounded bg-white p-3 text-sm outline-none active:bg-light-800 dark:bg-dark-600 hover:bg-light-700 focus:ring focus:ring-width-2 focus:ring-blurple dark:active:bg-dark-400 dark:hover:bg-dark-500"
|
||||
onClick={() => versionMenu.setOpen(false)}
|
||||
state={versionMenu}
|
||||
>
|
||||
{item}
|
||||
</MenuItem>
|
||||
</Link>
|
||||
)) ?? [],
|
||||
[versions, packageName, versionMenu],
|
||||
);
|
||||
|
||||
|
||||
@@ -1,16 +1,27 @@
|
||||
import { connect } from '@planetscale/database';
|
||||
import { get } from '@vercel/edge-config';
|
||||
import { NextResponse, type NextRequest } from 'next/server';
|
||||
import { PACKAGES } from './util/constants';
|
||||
|
||||
const sql = connect({
|
||||
url: process.env.DATABASE_URL!,
|
||||
async fetch(url, init) {
|
||||
delete init?.cache;
|
||||
return fetch(url, { ...init, next: { revalidate: 3_600 } });
|
||||
},
|
||||
});
|
||||
|
||||
async function fetchLatestVersion(packageName: string) {
|
||||
if (process.env.NEXT_PUBLIC_LOCAL_DEV || process.env.NEXT_PUBLIC_VERCEL_ENV === 'preview') {
|
||||
return 'main';
|
||||
}
|
||||
|
||||
const res = await fetch(`https://docs.discordjs.dev/api/info?package=${packageName}`, { cache: 'no-store' });
|
||||
const data: string[] = await res.json();
|
||||
const { rows } = await sql.execute('select version from documentation where name = ? order by version desc', [
|
||||
packageName,
|
||||
]);
|
||||
|
||||
return data.at(-2);
|
||||
// @ts-expect-error: https://github.com/planetscale/database-js/issues/71
|
||||
return rows[0].data.at(1);
|
||||
}
|
||||
|
||||
export default async function middleware(request: NextRequest) {
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
export const fetcher = async (url: string) => {
|
||||
const res = await fetch(url, { next: { revalidate: 3_600 } });
|
||||
return res.json();
|
||||
};
|
||||
Reference in New Issue
Block a user