Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/openstatusHQ/openstatus. ๐ซ Status page with uptime monitoring & API monitoring as code ๐ซ openstatus.dev
bun drizzle-orm monitoring monitoring-as-code nextjs observability on-call open-source shadcn-ui status-page statuspage synthetic-monitoring tinybird turso uptime uptime-checker uptime-monitor
Something went wrong. Try again.
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167import { getDocsPage } from "../docs";import { docsNavTree, findDocsNode } from "../docs.config";import { type MDXData, formatDate, getBlogPosts, getChangelogPosts, getComparePages, getCustomerPages, getGuides, getUseCasePages,} from "./index";
/** * Generates sitemap-style markdown listings for index and category pages * Used as fallback when MDX content is not found */export function generateListingForPath(pathname: string): string | null { const segments = pathname.split("/").filter(Boolean);
// Root path โ overview of all content if (segments.length === 0) { return generateRootListing(); }
// Docs containers (hub, sections) have no backing MDX file โ they render as // card grids; list their children from the nav tree. Leaves hit TIER 1. if (segments[0] === "docs") { return generateDocsListing(`/${segments.join("/")}`); }
const [category, subcategory, slug] = segments;
// Index pages: /blog, /changelog, etc. if (!subcategory) { switch (category) { case "blog": return generatePostsList(getBlogPosts(), "Blog Posts"); case "changelog": return generatePostsList(getChangelogPosts(), "Changelog"); case "compare": return generatePostsList(getComparePages(), "Comparisons"); case "guides": return generatePostsList(getGuides(), "Guides"); case "use-case": return generatePostsList(getUseCasePages(), "Use Cases"); case "customers": return generatePostsList(getCustomerPages(), "Customers"); default: return null; } }
// Category pages: /blog/category/engineering if (subcategory === "category" && slug) { return generateCategoryList(category, slug); }
return null;}
/** * Generate a markdown list from posts */function generatePostsList(posts: MDXData[], title: string): string { const sorted = posts.sort( (a, b) => b.metadata.publishedAt.getTime() - a.metadata.publishedAt.getTime(), );
const items = sorted .map( (post) => `- [${post.metadata.title}](${post.href}) - ${formatDate(post.metadata.publishedAt)}`, ) .join("\n");
return `# ${title}\n\n${items}\n`;}
/** * Generate category-filtered listings */function generateCategoryList(type: string, category: string): string | null { let posts: MDXData[]; let title: string;
switch (type) { case "blog": posts = getBlogPosts(); title = `Blog Posts - ${category}`; break; case "changelog": posts = getChangelogPosts(); title = `Changelog - ${category}`; break; default: return null; }
const filtered = posts.filter((p) => p.metadata.category === category);
if (filtered.length === 0) { return null; }
return generatePostsList(filtered, title);}
/** * Generate root listing with overview of all content sections */function generateRootListing(): string { const sections = [ { title: "Blog", posts: getBlogPosts(), path: "/blog" }, { title: "Changelog", posts: getChangelogPosts(), path: "/changelog" }, { title: "Comparisons", posts: getComparePages(), path: "/compare" }, { title: "Guides", posts: getGuides(), path: "/guides" }, { title: "Use Cases", posts: getUseCasePages(), path: "/use-case" }, { title: "Customers", posts: getCustomerPages(), path: "/customers" }, ];
const content = sections .map((section) => { const count = section.posts.length; const sortedPosts = section.posts.sort( (a, b) => b.metadata.publishedAt.getTime() - a.metadata.publishedAt.getTime(), );
const topPosts = sortedPosts .slice(0, 5) .map((p) => `- [${p.metadata.title}](${p.href})`) .join("\n");
const viewAll = count > 5 ? `\n- [View all ${count} ${section.title.toLowerCase()}...](${section.path})` : "";
return `## [${section.title}](${section.path}) (${count})\n\n${topPosts}${viewAll}`; }) .join("\n\n");
return `# OpenStatus Content\n\n${content}\n`;}
// List a docs container node's children. Any node in the tree with children is// listable (hub lists sections, a section lists pages); leaves return null and// fall through to their MDX file. Descriptions are resolved lazily per child.function generateDocsListing(href: string): string | null { const node = findDocsNode(docsNavTree(), href); if (!node?.children?.length) return null;
const intro = node.description ? `${node.description}\n\n` : ""; const items = node.children .map((child) => { const description = child.slug ? getDocsPage(child.slug)?.metadata.description : undefined; return `- [${child.label}](${child.href})${description ? `: ${description}` : ""}`; }) .join("\n");
return `# ${node.label}\n\n${intro}${items}\n`;}