mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 01:45:10 +03:00
## 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. [](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>
133 lines
3.4 KiB
TypeScript
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)
|
|
}
|