Skip to content

Commit

Permalink
Merge pull request #29 from solana-foundation/add-next-prev
Browse files Browse the repository at this point in the history
feat: added next prev record support
  • Loading branch information
nickfrosty authored Oct 26, 2023
2 parents c65e452 + 3b88f6b commit a18e0bb
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 29 deletions.
58 changes: 34 additions & 24 deletions src/pages/api/content/[[...slug]].ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
* based on the provided url `slug`
*/

import { SimpleRecordGroupName } from "@/types";
import { computeNavItem } from "@/utils/navItem";
import { NavItem, SimpleRecordGroupName } from "@/types";
import {
generateFlatNavItemListing,
generateNavItemListing,
} from "@/utils/navItem";
import {
allDeveloperGuides,
allDeveloperResources,
Expand Down Expand Up @@ -42,51 +45,58 @@ export default function handler(
if (!records) return res.status(404).json({ notFound: true });

// define the formatted href value to search for
// note: this effectively enforces that only href's that start with "/developers" are supported
const href = `${
slug[0].toLocaleLowerCase() == "docs" ? "" : "/developers"
}/${slug.join("/")}`;

// note: this effectively enforces that only href's that start with "/developers" are supported
// create a flat listing of all the nav items in order to locate the next, current, and prev records
const flatNavItems = generateFlatNavItemListing(
generateNavItemListing(records),
);

// init the record to be returned
let record;

// locate the correct record requested (via the url param)
for (let i = 0; i < records.length; i++) {
// @ts-ignore
const navItem = computeNavItem(records[i]);
// initialize the NavItem record trackers
let current: NavItem | null = null;
let next: NavItem | null = null;
let prev: NavItem | null = null;

for (let i = 0; i < flatNavItems.length; i++) {
// skip incorrect routes
if (
navItem.href != href &&
navItem.href != `/${href}` &&
records[i]?.altRoutes?.filter(route => route == href)?.[0] != href
flatNavItems[i].href != href &&
flatNavItems[i].href != `/${href}` &&
flatNavItems[i]?.altRoutes?.filter(route => route == href)?.[0] != href
) {
continue;
}

// set the requested record's data (weaving in the computed nav item data)
record = Object.assign(navItem, records[i]);

/**
* todo: support next/prev type records
* note: this will likely require processing the nav records?
*/
current = flatNavItems[i];
if (flatNavItems.length >= i - 1) prev = flatNavItems[i - 1];
if (flatNavItems.length >= i + 1) next = flatNavItems[i + 1];

// break out of the loop and stop processing
break;
}

if (!current) return res.status(404).json({ notFound: true });

// locate full content record
let record = records.find(
item =>
item._raw.sourceFilePath.toLowerCase() == current?.path?.toLowerCase(),
);
if (!record) return res.status(404).json({ notFound: true });

// remove the html formatted content (since it is undesired data to send over the wire)
// @ts-ignore
record.body = record.body.raw.trim();
if (typeof record.body.raw !== "undefined") {
// @ts-ignore
record.body = record.body.raw.trim();
}

// todo: preprocess the body content? (if desired in the future)

// todo: support sending related content records back to the client

// finally, return the json formatted listing of NavItems
return res.status(200).json(record);
// finally, return the json formatted listing of NavItems (with the next and prev records)
return res.status(200).json(Object.assign(current, record, { next, prev }));
}
12 changes: 7 additions & 5 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ export type SupportedDocTypes = Exclude<DocumentTypes, IgnoredDoc>;
* @dev when adding new group names, ensure the desired support is added in all
* other places the type `SimpleRecordGroupName` is used (e.g. api routes)
*/
export type SimpleRecordGroupName = "docs" | "guides" | "resources" | "workshops";
export type SimpleRecordGroupName =
| "docs"
| "guides"
| "resources"
| "workshops";

type NavItemBase = {
id: String;
Expand All @@ -24,10 +28,8 @@ type NavItemBase = {
href?: String;
sidebarSortOrder?: number;
metaOnly?: boolean;
/**
*
*/
items?: Array<any>;
/** List of alternate routes that should redirect to this same document */
altRoutes?: string[] | undefined;
};

export type NavItem = NavItemBase & {
Expand Down
19 changes: 19 additions & 0 deletions src/utils/navItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,24 @@ export function generateNavItemListing(
return sortNavItems(navItems);
}

/**
* Create a flat listing of all nav items provided
*
* note: normally, the provided `navItems` should be preprocessed by `generateNavItemListing`
*/
export function generateFlatNavItemListing(
navItems: Array<NavItem>,
): Array<NavItem> {
return navItems.flatMap(({ items, ...node }: NavItem) => {
if (typeof items !== "undefined") {
return [node as NavItem]
.concat(items)
.flatMap(children => generateFlatNavItemListing([children]));
}
return node;
});
}

/**
*
*/
Expand Down Expand Up @@ -175,6 +193,7 @@ export function computeNavItem(
label: doc?.sidebarLabel || doc?.title,
sidebarSortOrder: doc?.sidebarSortOrder,
metaOnly: doc?.metaOnly,
altRoutes: doc.altRoutes,
};

// compute an id based on the doc's path
Expand Down

0 comments on commit a18e0bb

Please sign in to comment.