From c030e2ca33102edc69b7c2c92691ea315db17906 Mon Sep 17 00:00:00 2001 From: nickfrosty Date: Thu, 30 Nov 2023 15:45:18 -0500 Subject: [PATCH] feat: catchup --- src/pages/api/nav/[[...group]].ts | 48 ++++++++++++++++++ src/pages/api/paths/[[...group]].ts | 79 +++++++++++++++++++++++++++++ src/pages/api/records/[group].ts | 5 +- src/types/index.ts | 7 ++- 4 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 src/pages/api/nav/[[...group]].ts create mode 100644 src/pages/api/paths/[[...group]].ts diff --git a/src/pages/api/nav/[[...group]].ts b/src/pages/api/nav/[[...group]].ts new file mode 100644 index 000000000..c5f1303fd --- /dev/null +++ b/src/pages/api/nav/[[...group]].ts @@ -0,0 +1,48 @@ +/** + * api route to generate the nav item listing for + * each supported content record `group` + */ + +import type { NextApiRequest, NextApiResponse } from "next"; +import { NavItem, SimpleRecordGroupName } from "@/types"; +import { generateNavItemListing } from "@/utils/navItem"; +import { + allDeveloperGuides, + // allDeveloperResources, + allSolanaDocs, + allDeveloperWorkshops, + allSolanaRPCDocs, +} from "contentlayer/generated"; + +export default function handler( + req: NextApiRequest, + res: NextApiResponse, +) { + // get the content record group + const group = req.query?.group?.toString() as SimpleRecordGroupName; + if (!group) return res.status(404).json({ notFound: true }); + + // retrieve the correct group's records by its simple group name + const records = ((group: SimpleRecordGroupName) => { + switch (group) { + case "rpc": + case "docs,rpc": + return allSolanaRPCDocs; + case "docs": + return allSolanaDocs; + case "guides": + return allDeveloperGuides; + // case "resources": + // return allDeveloperResources; + case "workshops": + return allDeveloperWorkshops; + } + })(group); + + if (!records) return res.status(404).json({ notFound: true }); + + const navItems = generateNavItemListing(records); + + // finally, return the json formatted listing of NavItems + return res.status(200).json(navItems); +} diff --git a/src/pages/api/paths/[[...group]].ts b/src/pages/api/paths/[[...group]].ts new file mode 100644 index 000000000..3b9fcf449 --- /dev/null +++ b/src/pages/api/paths/[[...group]].ts @@ -0,0 +1,79 @@ +/** + * api route to generate a path listing for + * each supported content record `group` + */ + +import type { NextApiRequest, NextApiResponse } from "next"; +import { NavItem, SimpleRecordGroupName } from "@/types"; +import { computeNavItem, shouldIgnoreRecord } from "@/utils/navItem"; +import { + allDeveloperGuides, + allDeveloperResources, + allSolanaDocs, + allDeveloperWorkshops, + allSolanaRPCDocs, +} from "contentlayer/generated"; + +export default function handler( + req: NextApiRequest, + res: NextApiResponse, +) { + // get the content record group + const group = req.query?.group?.toString() as SimpleRecordGroupName; + if (!group) return res.status(404).json({ notFound: true }); + + // retrieve the correct group's records by its simple group name + const records = ((group: SimpleRecordGroupName) => { + switch (group) { + case "rpc": + case "docs,rpc": + return allSolanaRPCDocs; + case "docs": + return allSolanaDocs; + case "guides": + return allDeveloperGuides; + case "resources": + return allDeveloperResources; + case "workshops": + return allDeveloperWorkshops; + } + })(group); + + if (!records) return res.status(404).json({ notFound: true }); + + // init the listing response + const listing: Array = []; + + /** + * todo: assorted things + * - better support for external links + */ + + // compute the path data to return + records.map(record => { + if (shouldIgnoreRecord({ fileName: record._raw.sourceFileName })) return; + + // @ts-ignore + const navItem = computeNavItem(record); + + if (!navItem.href || !!record.isExternal) return; + + listing.push(navItem); + + // handle adding each of the alternative routes into the path listing + if (!!record?.altRoutes?.length) { + record.altRoutes.forEach(route => { + if (!!route?.trim()) { + listing.push( + Object.assign(navItem, { + href: route.trim(), + }), + ); + } + }); + } + }); + + // finally, return the json formatted listing + return res.status(200).json(listing); +} diff --git a/src/pages/api/records/[group].ts b/src/pages/api/records/[group].ts index b3a64ca56..20ca08e35 100644 --- a/src/pages/api/records/[group].ts +++ b/src/pages/api/records/[group].ts @@ -9,6 +9,7 @@ import { allDeveloperResources, allSolanaDocs, allDeveloperWorkshops, + allSolanaRPCDocs, } from "contentlayer/generated"; import { simplifyRecords } from "@/utils/parsers"; @@ -23,6 +24,9 @@ export default function handler( // retrieve the correct group's records by its simple group name let records: SupportedDocTypes[] = ((group: SimpleRecordGroupName) => { switch (group) { + case "rpc": + case "docs,rpc": + return allSolanaRPCDocs; case "docs": return allSolanaDocs; case "guides": @@ -40,7 +44,6 @@ export default function handler( records = simplifyRecords(records); // todo: add pagination support? - // todo: migrate to trpc and add filters support as well // finally, return the json formatted listing return res.status(200).json(records); diff --git a/src/types/index.ts b/src/types/index.ts index 46f68a2e3..4903b47c8 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -17,6 +17,8 @@ export type SupportedDocTypes = Exclude; */ export type SimpleRecordGroupName = | "docs" + | "rpc" + | "docs,rpc" // note: this is to support stringify-ing the route via the url | "guides" | "resources" | "workshops"; @@ -28,7 +30,10 @@ type NavItemBase = { href?: String; sidebarSortOrder?: number; metaOnly?: boolean; - /** List of alternate routes that should redirect to this same document */ + /** + * + */ + items?: Array; altRoutes?: string[] | undefined; };