Files
supabase/apps/docs/features/docs/NavigationPageStatus.utils.ts
T
a93eef6848 docs: move AI tools section (#45795)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added an "AI Tools" guides section with landing, overview, and
troubleshooting pages; guides render from Markdown.

* **Documentation**
* New AI Tools guides: local development, Quickstart, CLI overview,
troubleshooting, and detailed overview pages.

* **Chores**
* Site navigation updated to include an AI Tools entry and renamed
subsection to "AI"; added permanent redirects from prior Getting Started
AI URLs to the new AI Tools locations.

* **Bug Fixes**
* Updated internal guide links so AI prompt pages point to the new AI
Tools paths.

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45795)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Greg Richardson <greg.nmr@gmail.com>
2026-05-13 05:29:49 +00:00

133 lines
3.4 KiB
TypeScript

import { type NavMenuConstant } from '~/components/Navigation/Navigation.types'
import {
ai,
ai_tools,
api,
auth,
cron,
database,
deployment,
functions,
gettingstarted,
GLOBAL_MENU_ITEMS,
graphql,
integrations,
local_development,
platform,
queues,
realtime,
security,
self_hosting,
storage,
telemetry,
} from '~/components/Navigation/NavigationMenu/NavigationMenu.constants'
// Map of section names to their nav constants
const SECTION_NAV_MAPS: Record<string, NavMenuConstant> = {
ai,
api,
auth,
cron,
database,
deployment,
functions,
'getting-started': gettingstarted,
graphql,
integrations,
'ai-tools': ai_tools,
'local-development': local_development,
platform,
queues,
realtime,
security,
'self-hosting': self_hosting,
storage,
telemetry,
}
interface ConditionalNavItem {
url?: string
href?: string
enabled?: boolean
items?: Readonly<ConditionalNavItem[]>
menuItems?: Readonly<ConditionalNavItem[][]>
}
/**
* Recursively walks navigation items and collects all disabled paths.
* If a parent is disabled, all its children are also considered disabled.
*/
function collectDisabledPaths(
items: Readonly<ConditionalNavItem[] | ConditionalNavItem[][]>,
disabledPaths: Set<string>,
parentDisabled: boolean = false
): void {
for (const item of items) {
if (Array.isArray(item)) {
// Handle nested arrays (like in GLOBAL_MENU_ITEMS)
collectDisabledPaths(item, disabledPaths, parentDisabled)
} else {
const isCurrentDisabled = parentDisabled || item.enabled === false
const itemUrl = item.url || item.href
if (itemUrl && itemUrl.startsWith('/guides/')) {
const normalizedUrl = normalizeUrl(itemUrl)
if (isCurrentDisabled) {
disabledPaths.add(normalizedUrl)
}
}
// Recursively check children, passing down the disabled status
if (item.items) {
collectDisabledPaths(item.items, disabledPaths, isCurrentDisabled)
}
if (item.menuItems) {
collectDisabledPaths(item.menuItems, disabledPaths, isCurrentDisabled)
}
}
}
}
/**
* Normalizes URLs for comparison by removing leading/trailing slashes and ensuring consistent format
*/
function normalizeUrl(url: string): string {
return url.replace(/^\/+|\/+$/g, '').toLowerCase()
}
/**
* Creates and caches the set of all disabled guide paths.
* This is computed once and reused across all checks.
*/
let cachedDisabledPaths: Set<string> | null = null
function getDisabledGuidePaths(): Set<string> {
if (cachedDisabledPaths === null) {
cachedDisabledPaths = new Set<string>()
// Collect disabled paths from global menu items
collectDisabledPaths(GLOBAL_MENU_ITEMS, cachedDisabledPaths)
// Collect disabled paths from section-specific navigation
Object.values(SECTION_NAV_MAPS).forEach((sectionNav) => {
if (sectionNav.items) {
collectDisabledPaths([sectionNav], cachedDisabledPaths!)
}
})
}
return cachedDisabledPaths
}
/**
* Checks if a guides page is enabled based on the navigation menu configuration
*
* @param guidesPath - The path to the guides page (e.g., "/guides/auth/users")
* @returns true if enabled, false if disabled
*/
export function checkGuidePageEnabled(guidesPath: string): boolean {
const disabledPaths = getDisabledGuidePaths()
const normalizedPath = normalizeUrl(guidesPath)
return !disabledPaths.has(normalizedPath)
}