nimbus-docs 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +25 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +692 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/client.d.ts +167 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +367 -0
- package/dist/client.js.map +1 -0
- package/dist/content.d.ts +126 -0
- package/dist/content.d.ts.map +1 -0
- package/dist/content.js +57 -0
- package/dist/content.js.map +1 -0
- package/dist/index.d.ts +255 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1478 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/pkgm.d.ts +41 -0
- package/dist/lib/pkgm.d.ts.map +1 -0
- package/dist/lib/pkgm.js +76 -0
- package/dist/lib/pkgm.js.map +1 -0
- package/dist/schemas.d.ts +164 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +110 -0
- package/dist/schemas.js.map +1 -0
- package/dist/types.d.ts +274 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/package.json +81 -0
- package/src/components/NimbusHead.astro +161 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["PRIMARY_COLLECTION","getBreadcrumbs","getPrevNext","buildPrevNext","buildBreadcrumbs"],"sources":["../src/_internal/runtime-config.ts","../src/_internal/content.ts","../src/_internal/sidebar.ts","../src/_internal/transform.ts","../src/_internal/navigation.ts","../src/_internal/toc.ts","../src/_internal/git-last-updated.ts","../src/_internal/parse-components-registry.ts","../src/_internal/code-transformers.ts","../src/_internal/levenshtein.ts","../src/_internal/validate-mdx-content.ts","../src/_internal/validate.ts","../src/_internal/virtual-config.ts","../src/integration.ts","../src/index.ts"],"sourcesContent":["/**\n * Runtime config bridge.\n *\n * Reads the user's validated NimbusConfig from `virtual:nimbus/config`,\n * which is provided by the Vite plugin our integration registers.\n *\n * **The import is dynamic on purpose.** Astro's config loader (in plain\n * Node) eagerly imports the whole framework bundle when it loads our\n * default export from `astro.config.ts`. A top-level static\n * `import \"virtual:...\"` would crash there because Vite hasn't booted\n * yet. Dynamic import keeps the load deferred until a page actually\n * calls a helper at request/render time.\n */\n\nimport type { NimbusConfig } from \"../types.js\";\n\ndeclare module \"virtual:nimbus/config\" {\n export const config: NimbusConfig;\n}\n\nlet _cached: NimbusConfig | null = null;\n\nexport async function loadNimbusConfig(): Promise<NimbusConfig> {\n if (_cached) return _cached;\n const mod = await import(\"virtual:nimbus/config\");\n _cached = mod.config;\n return _cached;\n}\n","/**\n * Content collection access for helpers.\n *\n * Dynamic import of `astro:content` for the same reason as\n * runtime-config: Astro's config loader runs in plain Node, where\n * `astro:content` doesn't exist. We defer to call time, which only\n * happens at page render.\n *\n * There is intentionally no global \"list of collections Nimbus knows\n * about\" — the framework doesn't try to mirror what\n * `content.config.ts` registers. Callers that need entries from\n * multiple collections pass them explicitly; the sidebar builder\n * derives its list from `sidebar.items` references.\n */\n\nimport type { CollectionEntry } from \"astro:content\";\n\n/** Primary collection name. Hard-coded — see also `getDocsStaticPaths`. */\nconst PRIMARY_COLLECTION = \"docs\";\n\n/**\n * Return visible entries from one or more collections. Drafts are\n * filtered out in production builds (matching the existing\n * single-collection behaviour).\n *\n * Defaults to `[\"docs\"]` — the framework's primary collection.\n * Cross-collection callers (llms.txt aggregators, custom indexes,\n * etc.) pass an explicit list.\n *\n * Returns a flat `CollectionEntry<string>[]` so cross-collection\n * traversal doesn't need to know the user's collection names at type\n * time. Callers that need per-collection type safety should call\n * `getCollection(\"api\")` directly.\n */\nexport async function getVisibleEntries(\n collections: string[] = [PRIMARY_COLLECTION],\n): Promise<CollectionEntry<string>[]> {\n const { getCollection } = await import(\"astro:content\");\n const lists = await Promise.all(\n collections.map((name) =>\n getCollection(name).catch(() => [] as CollectionEntry<string>[]),\n ),\n );\n const all = lists.flat();\n return import.meta.env.PROD\n ? all.filter((entry: CollectionEntry<string>) => !entry.data.draft)\n : all;\n}\n\n/**\n * Return visible entries grouped by collection. Used by the sidebar\n * builder so `collection:` autogenerate can look up entries by name\n * without re-fetching.\n */\nexport async function getVisibleEntriesByCollection(\n collections: string[],\n): Promise<Record<string, CollectionEntry<string>[]>> {\n const { getCollection } = await import(\"astro:content\");\n const out: Record<string, CollectionEntry<string>[]> = {};\n await Promise.all(\n collections.map(async (name) => {\n const all = await getCollection(name).catch(\n () => [] as CollectionEntry<string>[],\n );\n out[name] = import.meta.env.PROD\n ? all.filter((entry: CollectionEntry<string>) => !entry.data.draft)\n : all;\n }),\n );\n return out;\n}\n","// ---------------------------------------------------------------------------\n// sidebar.ts — Hybrid sidebar builder\n//\n// `buildSidebarTree` returns the un-scoped tree. The public `getSidebar`\n// helper applies `scopeToCurrentSection` on top so each page only renders\n// its own top-level section in the rail. Callers that need the full tree\n// (e.g. the section-tabs derivation in `deriveSidebarSections`) skip the\n// scoping step.\n//\n// Three sources for the tree:\n// 1. Config-defined: items array in docs.config.ts takes priority\n// 2. Auto-generated: `autogenerate: { directory }` scans filesystem\n// 3. Filesystem fallback: if no config items, build from all docs entries\n// ---------------------------------------------------------------------------\n\nimport type {\n SidebarBadge,\n SidebarConfig,\n SidebarConfigItem as ConfigItem,\n SidebarExternalLinkItem,\n SidebarGroupItem,\n SidebarItem,\n SidebarLinkItem,\n SidebarSection,\n} from \"../types.js\";\n\n/** Minimal shape needed from content entries */\ninterface CollectionEntry {\n id: string;\n data: {\n title: string;\n draft?: boolean;\n sidebar?: {\n order?: number;\n label?: string;\n badge?: SidebarBadge;\n hidden?: boolean;\n hideChildren?: boolean;\n };\n };\n}\n\n// ---------------------------------------------------------------------------\n// Sort\n// ---------------------------------------------------------------------------\n\nconst sortKeyByItem = new WeakMap<SidebarItem, string>();\n\nfunction sortSidebarItems(a: SidebarItem, b: SidebarItem): number {\n const orderDiff = a.order - b.order;\n if (orderDiff !== 0) return orderDiff;\n\n const keyA = sortKeyByItem.get(a) ?? (\"href\" in a ? a.href : a.label);\n const keyB = sortKeyByItem.get(b) ?? (\"href\" in b ? b.href : b.label);\n const keyDiff = keyA.localeCompare(keyB);\n if (keyDiff !== 0) return keyDiff;\n\n return a.type.localeCompare(b.type);\n}\n\n// ---------------------------------------------------------------------------\n// Link normalization\n// ---------------------------------------------------------------------------\n\n/** Ensure internal href has leading /, no trailing slash (except root) */\nfunction normalizeInternalHref(href: string): string {\n let h = href.split(\"?\")[0].split(\"#\")[0];\n if (!h.startsWith(\"/\")) h = `/${h}`;\n if (h.length > 1 && h.endsWith(\"/\")) h = h.slice(0, -1);\n return h;\n}\n\n/** Strip query and hash for active-state matching */\nfunction stripQueryHash(href: string): string {\n return href.split(\"?\")[0].split(\"#\")[0];\n}\n\n// ---------------------------------------------------------------------------\n// Entry index — shared utilities for looking up content entries\n// ---------------------------------------------------------------------------\n\nfunction buildEntryIndex(entries: CollectionEntry[]) {\n const visible = entries.filter((e) => !e.data.sidebar?.hidden);\n const byId = new Map<string, CollectionEntry>();\n for (const entry of visible) {\n byId.set(entry.id, entry);\n }\n\n const hasChildren = new Set<string>();\n for (const entry of visible) {\n const parts = entry.id.split(\"/\");\n for (let i = 1; i < parts.length; i++) {\n hasChildren.add(parts.slice(0, i).join(\"/\"));\n }\n }\n\n return { visible, byId, hasChildren };\n}\n\n// ---------------------------------------------------------------------------\n// Link/group creation from content entries\n// ---------------------------------------------------------------------------\n\n/** Compose a final href for an entry. `hrefPrefix` is the collection mount path (e.g. `/api`). */\nfunction joinHref(hrefPrefix: string, entryId: string): string {\n // hrefPrefix is \"\" for root-mounted collections, \"/api\" for prefixed ones.\n // Drop a trailing slash on the prefix to avoid `/api//foo`.\n const prefix = hrefPrefix.replace(/\\/$/, \"\");\n return `${prefix}/${entryId}`;\n}\n\nfunction createLink(\n entry: CollectionEntry,\n currentPath: string,\n hrefPrefix = \"\",\n): SidebarLinkItem {\n const href = joinHref(hrefPrefix, entry.id);\n const badge = entry.data.draft\n ? (entry.data.sidebar?.badge ?? { text: \"Draft\", variant: \"warning\" })\n : entry.data.sidebar?.badge;\n\n const link: SidebarLinkItem = {\n type: \"link\",\n label: entry.data.sidebar?.label ?? entry.data.title,\n href,\n isCurrent: currentPath === href,\n badge,\n order: entry.data.sidebar?.order ?? Number.MAX_VALUE,\n };\n\n sortKeyByItem.set(link, entry.id);\n return link;\n}\n\n// ---------------------------------------------------------------------------\n// Filesystem tree builder (used for autogenerate + fallback)\n// ---------------------------------------------------------------------------\n\nfunction buildFilesystemTree(\n entries: CollectionEntry[],\n currentPath: string,\n directory?: string,\n hrefPrefix = \"\",\n): SidebarItem[] {\n const { visible, byId, hasChildren } = buildEntryIndex(entries);\n\n // Filter to entries under the target directory\n const scoped = directory ? visible.filter((e) => e.id === directory || e.id.startsWith(`${directory}/`)) : visible;\n\n function buildLevel(parentPath: string): SidebarItem[] {\n const result: SidebarItem[] = [];\n const groupsAtLevel = new Map<string, SidebarGroupItem>();\n\n for (const entry of scoped) {\n if (entry.id === \"index\") continue;\n\n const id = entry.id;\n const relativeTo = directory ?? \"\";\n const relativeId = relativeTo ? (id === relativeTo ? \"\" : id.slice(relativeTo.length + 1)) : id;\n\n // Skip if this entry doesn't belong at this level\n if (parentPath === \"\") {\n if (!relativeId || relativeId.includes(\"/\") === false) {\n // Top-level entry relative to scope\n if (!relativeId) continue; // directory index, handled as group\n\n if (hasChildren.has(id)) {\n if (!groupsAtLevel.has(id)) {\n const group = createGroupFromEntry(id, entry, currentPath, byId);\n groupsAtLevel.set(id, group);\n result.push(group);\n }\n } else {\n result.push(createLink(entry, currentPath, hrefPrefix));\n }\n } else {\n // Multi-segment — belongs under first segment group\n const firstSeg = relativeId.split(\"/\")[0];\n const topDir = directory ? `${directory}/${firstSeg}` : firstSeg;\n if (!groupsAtLevel.has(topDir)) {\n const indexEntry = byId.get(topDir);\n const group = createGroupFromEntry(topDir, indexEntry, currentPath, byId);\n groupsAtLevel.set(topDir, group);\n result.push(group);\n }\n }\n } else {\n if (!id.startsWith(`${parentPath}/`)) continue;\n const remainder = id.slice(parentPath.length + 1);\n const remainderParts = remainder.split(\"/\");\n\n if (remainderParts.length === 1) {\n if (hasChildren.has(id)) {\n if (!groupsAtLevel.has(id)) {\n const group = createGroupFromEntry(id, entry, currentPath, byId);\n groupsAtLevel.set(id, group);\n result.push(group);\n }\n } else {\n result.push(createLink(entry, currentPath, hrefPrefix));\n }\n } else {\n const nextDir = `${parentPath}/${remainderParts[0]}`;\n if (!groupsAtLevel.has(nextDir)) {\n const indexEntry = byId.get(nextDir);\n const group = createGroupFromEntry(nextDir, indexEntry, currentPath, byId);\n groupsAtLevel.set(nextDir, group);\n result.push(group);\n }\n }\n }\n }\n\n // Recursively build children for each group\n for (const [groupPath, group] of groupsAtLevel) {\n const nestedChildren = buildLevel(groupPath);\n group.children = [...group.children, ...nestedChildren].sort(sortSidebarItems);\n\n if (group.children.length > 0) {\n const minChildOrder = Math.min(...group.children.map((item) => item.order));\n group.order = Math.min(group.order, minChildOrder);\n }\n }\n\n return result.sort(sortSidebarItems);\n }\n\n function createGroupFromEntry(\n dirPath: string,\n indexEntry: CollectionEntry | undefined,\n currentPath: string,\n _byId: Map<string, CollectionEntry>,\n ): SidebarGroupItem {\n const dirSegment = dirPath.split(\"/\").pop()!;\n // Starlight parity: group label comes from the directory name, not the index page title.\n // Use sidebar.label on the index page to override, but never use title (that's for the link).\n const groupLabel = indexEntry?.data.sidebar?.label ?? formatLabel(dirSegment);\n const groupOrder = indexEntry?.data.sidebar?.order ?? Number.MAX_VALUE;\n const children: SidebarItem[] = [];\n\n // Index page as child link inside the group\n // (hideChildren is handled later by processHideChildren)\n if (indexEntry) {\n children.push(createLink(indexEntry, currentPath, hrefPrefix));\n }\n\n const group: SidebarGroupItem = {\n type: \"group\",\n label: groupLabel,\n order: groupOrder,\n badge: indexEntry?.data.sidebar?.badge,\n children,\n _indexId: indexEntry?.id,\n };\n\n sortKeyByItem.set(group, dirPath);\n return group;\n }\n\n // For directory-scoped autogenerate, just build the children level\n if (directory) {\n return buildLevel(directory);\n }\n\n return buildLevel(\"\");\n}\n\n// ---------------------------------------------------------------------------\n// Config-driven builder\n// ---------------------------------------------------------------------------\n\nfunction resolveConfigItems(\n configItems: ConfigItem[],\n entriesByCollection: Record<string, CollectionEntry[]>,\n primaryCollection: string,\n currentPath: string,\n orderStart: number = 0,\n): SidebarItem[] {\n const primaryEntries = entriesByCollection[primaryCollection] ?? [];\n const { byId } = buildEntryIndex(primaryEntries);\n const result: SidebarItem[] = [];\n\n for (let i = 0; i < configItems.length; i++) {\n const item = configItems[i];\n const order = orderStart + i;\n\n if (typeof item === \"string\") {\n // Bare slug references resolve against the primary collection only.\n // Cross-collection links use the `{ label, link }` form with an\n // explicit href.\n const entry = byId.get(item);\n if (entry) {\n const link = createLink(entry, currentPath);\n link.order = order;\n result.push(link);\n } else {\n // Warn but don't crash — might be a typo\n console.warn(\n `[sidebar] Page \"${item}\" referenced in config but not found in primary collection \"${primaryCollection}\"`,\n );\n }\n } else if (\"link\" in item) {\n const isExternal = !item.link.startsWith(\"/\");\n if (isExternal) {\n const extLink: SidebarExternalLinkItem = {\n type: \"external\",\n label: item.label,\n href: item.link,\n badge: item.badge,\n order,\n };\n result.push(extLink);\n } else {\n // Internal link with custom label\n const href = normalizeInternalHref(item.link);\n const matchPath = stripQueryHash(href);\n\n // Best-effort validation: warn only if the link looks like a\n // primary-collection slug and doesn't resolve. Cross-collection\n // links (e.g. `/api/users`) intentionally bypass this check.\n const lookup = href.slice(1);\n const looksLikePrimaryRoot = !lookup.includes(\"/\");\n if (looksLikePrimaryRoot && href !== \"/\" && !byId.has(lookup)) {\n console.warn(\n `[sidebar] Internal link \"${item.link}\" (label: \"${item.label}\") does not match any entry in primary collection \"${primaryCollection}\"`,\n );\n }\n\n const link: SidebarLinkItem = {\n type: \"link\",\n label: item.label,\n href,\n isCurrent: currentPath === matchPath,\n badge: item.badge,\n order,\n };\n result.push(link);\n }\n } else if (\"autogenerate\" in item) {\n // Two flavours: directory-within-primary, or named collection.\n let autoItems: SidebarItem[];\n if (\"collection\" in item.autogenerate) {\n const collectionName = item.autogenerate.collection;\n const collectionEntries = entriesByCollection[collectionName];\n if (!collectionEntries) {\n console.warn(\n `[sidebar] autogenerate references collection \"${collectionName}\" which is not registered in nimbus.config.collections; skipping`,\n );\n autoItems = [];\n } else {\n // Resolve the mount prefix. Primary collection mounts at root\n // (no prefix) by convention; other collections default to\n // `/<name>` unless explicitly overridden.\n const explicit = item.autogenerate.prefix;\n const isPrimary = collectionName === primaryCollection;\n const prefix = explicit ?? (isPrimary ? \"\" : `/${collectionName}`);\n autoItems = buildFilesystemTree(\n collectionEntries,\n currentPath,\n undefined,\n prefix,\n );\n }\n } else {\n // directory-scoped autogenerate operates on the primary collection\n autoItems = buildFilesystemTree(\n primaryEntries,\n currentPath,\n item.autogenerate.directory,\n );\n }\n\n // If the config item has a label, wrap in a group\n if (item.label) {\n const group: SidebarGroupItem = {\n type: \"group\",\n label: item.label,\n order,\n collapsed: item.collapsed,\n badge: item.badge,\n children: autoItems,\n };\n result.push(group);\n } else {\n // Inline autogenerate (inside a manual group's items)\n if (item.collapsed !== undefined) {\n for (const ai of autoItems) {\n if (ai.type === \"group\") {\n ai.collapsed = item.collapsed;\n }\n }\n }\n result.push(...autoItems);\n }\n } else if (\"items\" in item) {\n // Manual group\n const children = resolveConfigItems(\n item.items,\n entriesByCollection,\n primaryCollection,\n currentPath,\n );\n const group: SidebarGroupItem = {\n type: \"group\",\n label: item.label,\n order,\n collapsed: item.collapsed,\n badge: item.badge,\n children,\n };\n result.push(group);\n }\n }\n\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Scoping — filter to current top-level section\n// ---------------------------------------------------------------------------\n\n/**\n * Return only the children of the top-level group containing the current\n * page. Falls back to the full tree if the current page isn't inside any\n * group (e.g. a top-level link, or a path that doesn't resolve).\n */\nexport function scopeToCurrentSection(items: SidebarItem[], currentPath: string): SidebarItem[] {\n const currentSegment = currentPath.split(\"/\").filter(Boolean)[0];\n if (!currentSegment) return items;\n\n for (const item of items) {\n if (item.type === \"group\") {\n if (hasActivePage(item, currentPath)) {\n return item.children;\n }\n }\n }\n\n return items;\n}\n\nfunction hasActivePage(item: SidebarItem, currentPath: string): boolean {\n if (item.type === \"link\") return item.isCurrent === true;\n if (item.type === \"external\") return false;\n return item.children.some((child) => hasActivePage(child, currentPath));\n}\n\n// ---------------------------------------------------------------------------\n// Section derivation — top-level groups as nav sections\n// ---------------------------------------------------------------------------\n\n/**\n * Derive one section per top-level group in the sidebar tree. Used by\n * `Header.astro` to render the section tab strip. Caller must pass the\n * *un-scoped* tree (the result of `buildSidebarTree`, not `getSidebar`);\n * otherwise only the current section's children are visible and the\n * derivation collapses to a single item.\n */\nexport function deriveSidebarSections(items: SidebarItem[]): SidebarSection[] {\n return items.flatMap((item) => {\n if (item.type !== \"group\") return [];\n const links = flattenLinks(item.children);\n if (links.length === 0) return [];\n return [\n {\n label: item.label,\n href: links[0].href,\n isActive: links.some((link) => link.isCurrent === true),\n },\n ];\n });\n}\n\n/** Depth-first walk; collect every internal link descendant. */\nfunction flattenLinks(items: SidebarItem[]): SidebarLinkItem[] {\n const out: SidebarLinkItem[] = [];\n for (const item of items) {\n if (item.type === \"link\") out.push(item);\n else if (item.type === \"group\") out.push(...flattenLinks(item.children));\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Build the un-scoped sidebar tree from config + content entries.\n *\n * `entriesByCollection` is a name → entries map covering every\n * collection the user listed in `NimbusConfig.collections`. The\n * `primaryCollection` (first entry of that list) is what\n * filesystem-fallback, `directory:` autogenerate, and bare-slug\n * references read from. Other collections only contribute when an\n * explicit `autogenerate: { collection: \"<name>\" }` references them.\n *\n * - If config has items: resolve them (config takes priority)\n * - If config has no items: auto-generate from primary collection\n *\n * Always returns the full top-level tree. Scoping (showing only the\n * current section's children in the rail) is applied by the public\n * `getSidebar` helper via `scopeToCurrentSection`.\n */\nexport function buildSidebarTree(\n entriesByCollection: Record<string, CollectionEntry[]>,\n primaryCollection: string,\n currentPath: string,\n config?: SidebarConfig,\n): SidebarItem[] {\n const primaryEntries = entriesByCollection[primaryCollection] ?? [];\n let items: SidebarItem[];\n\n if (config?.items && config.items.length > 0) {\n // Config-driven\n items = resolveConfigItems(\n config.items,\n entriesByCollection,\n primaryCollection,\n currentPath,\n );\n } else {\n // Filesystem fallback — primary collection only. Cross-collection\n // sidebars require explicit config items.\n items = buildFilesystemTree(primaryEntries, currentPath);\n }\n\n // Apply hideChildren — pool entries across all collections so a\n // non-primary `autogenerate: { collection }` group's index lookup\n // resolves correctly.\n const pooledEntries = Object.values(entriesByCollection).flat();\n items = processHideChildren(items, pooledEntries);\n\n return items;\n}\n\n/**\n * Process hideChildren: replace groups whose index has hideChildren=true\n * with a single link to the index page.\n */\nfunction processHideChildren(items: SidebarItem[], entries: CollectionEntry[]): SidebarItem[] {\n const entryById = new Map<string, CollectionEntry>();\n for (const e of entries) entryById.set(e.id, e);\n\n function process(items: SidebarItem[]): SidebarItem[] {\n const result: SidebarItem[] = [];\n for (const item of items) {\n if (item.type !== \"group\") {\n result.push(item);\n continue;\n }\n\n // Check if this group's index entry has hideChildren\n if (item._indexId) {\n const entry = entryById.get(item._indexId);\n if (entry?.data.sidebar?.hideChildren) {\n // Find the index link in children (by matching href to the index ID)\n const indexHref = `/${item._indexId}`;\n const indexLink = item.children.find((c): c is SidebarLinkItem => c.type === \"link\" && c.href === indexHref);\n if (indexLink) {\n // Replace group with single link\n const link: SidebarLinkItem = {\n ...indexLink,\n label: item.label,\n };\n result.push(link);\n continue;\n }\n }\n }\n\n // Recurse into children\n item.children = process(item.children);\n result.push(item);\n }\n return result;\n }\n\n return process(items);\n}\n\n/**\n * Walk a sidebar config items array (recursively, through nested\n * `items:` groups) and collect every collection name referenced by an\n * `autogenerate: { collection: ... }` entry.\n *\n * The framework uses this to figure out which collections to load for\n * the sidebar — there's no separate `collections: string[]` config\n * field. The primary collection (`docs`) is always included by the\n * caller; this helper returns only the *extra* names referenced by\n * sidebar items.\n */\nexport function collectSidebarCollectionRefs(\n items: ConfigItem[] | undefined,\n): string[] {\n if (!items) return [];\n const found = new Set<string>();\n function walk(items: ConfigItem[]): void {\n for (const item of items) {\n if (typeof item === \"string\") continue;\n if (\"autogenerate\" in item && \"collection\" in item.autogenerate) {\n found.add(item.autogenerate.collection);\n } else if (\"items\" in item) {\n walk(item.items);\n }\n }\n }\n walk(items);\n return [...found];\n}\n\n/** Flatten sidebar tree into a list of links (for pagination) */\nexport function flattenSidebar(items: SidebarItem[]): SidebarLinkItem[] {\n const flat: SidebarLinkItem[] = [];\n for (const item of items) {\n if (item.type === \"link\") {\n flat.push(item);\n } else if (item.type === \"group\") {\n flat.push(...flattenSidebar(item.children));\n }\n }\n return flat;\n}\n\nfunction formatLabel(segment: string): string {\n return segment.replace(/-/g, \" \").replace(/\\b\\w/g, (char) => char.toUpperCase());\n}\n\n// ---------------------------------------------------------------------------\n// Sidebar hash — deterministic hash of sidebar structure for state invalidation.\n// Uses DJBX33A (same as Starlight). When the hash changes (pages added/removed,\n// labels renamed), persisted sidebar state is discarded.\n// ---------------------------------------------------------------------------\n\nfunction buildSidebarIdentity(items: SidebarItem[]): string {\n return items\n .flatMap((item) =>\n item.type === \"group\"\n ? item.label + buildSidebarIdentity(item.children)\n : item.label + (\"href\" in item ? item.href : \"\"),\n )\n .join(\"\");\n}\n\n/** Hash the sidebar structure into a short string for sessionStorage invalidation. */\nexport function sidebarHash(items: SidebarItem[]): string {\n const identity = buildSidebarIdentity(items);\n let hash = 0;\n for (let i = 0; i < identity.length; i++) {\n hash = (hash << 5) - hash + identity.charCodeAt(i);\n }\n return (hash >>> 0).toString(36).padStart(7, \"0\");\n}\n","/**\n * MDX → markdown transform for AI-readable static routes.\n *\n * This intentionally starts small and dependency-free: it operates on the\n * raw MDX body that Astro's content layer exposes and maps the starter's\n * default components to plain markdown equivalents. The route that calls this\n * lives in user code, so replacing or bypassing this transformer is a one-line\n * edit.\n */\n\nexport interface MarkdownComponentRenderContext {\n name: string;\n attrs: Record<string, string | boolean>;\n children: string;\n}\n\nexport type MarkdownComponentRenderer = (\n context: MarkdownComponentRenderContext,\n) => string;\n\nexport interface RenderEntryAsMarkdownOptions {\n /**\n * Override how specific MDX components are rendered. Keys are component\n * names (e.g. `Aside`, `Tabs`, `PackageManagers`).\n */\n componentMap?: Record<string, MarkdownComponentRenderer>;\n /** Strip YAML frontmatter if the raw body includes it. Default: true. */\n stripFrontmatter?: boolean;\n}\n\ninterface MarkdownEntry {\n body?: string;\n}\n\nfunction protectCode(markdown: string): { markdown: string; restore: (value: string) => string } {\n const protectedChunks: string[] = [];\n function store(chunk: string): string {\n const token = `@@NIMBUS_MD_CODE_${protectedChunks.length}@@`;\n protectedChunks.push(chunk.startsWith(\"```\") ? chunk.replace(/\\n[ \\t]{4}/g, \"\\n\") : chunk);\n return token;\n }\n\n // Fenced blocks first so inline-code protection doesn't touch backticks inside.\n let next = markdown.replace(/```[\\s\\S]*?```/g, store);\n next = next.replace(/`[^`\\n]+`/g, store);\n\n return {\n markdown: next,\n restore(value: string): string {\n return value.replace(/@@NIMBUS_MD_CODE_(\\d+)@@/g, (_match, index: string) =>\n protectedChunks[Number(index)] ?? \"\",\n );\n },\n };\n}\n\nfunction parseAttrs(raw = \"\"): Record<string, string | boolean> {\n const attrs: Record<string, string | boolean> = {};\n const re = /([A-Za-z_:][\\w:.-]*)(?:\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|\\{([^}]*)\\}|([^\\s>]+)))?/g;\n for (const match of raw.matchAll(re)) {\n const [, name, dq, sq, expr, bare] = match;\n if (!name) continue;\n attrs[name] = dq ?? sq ?? expr?.trim() ?? bare ?? true;\n }\n return attrs;\n}\n\nfunction cleanChildren(children: string): string {\n return children\n .replace(/^\\s+/g, \"\")\n .replace(/\\s+$/g, \"\")\n .replace(/\\n[ \\t]+/g, \"\\n\");\n}\n\nfunction blockquote(body: string): string {\n return body\n .split(\"\\n\")\n .map((line) => (line ? `> ${line}` : \">\"))\n .join(\"\\n\");\n}\n\nfunction asTitle(value: string | boolean | undefined, fallback: string): string {\n return typeof value === \"string\" && value.trim() ? value.trim() : fallback;\n}\n\nfunction renderPackageManagers(attrs: Record<string, string | boolean>): string {\n const pkg = typeof attrs.pkg === \"string\" ? attrs.pkg : undefined;\n const args = typeof attrs.args === \"string\" ? attrs.args : undefined;\n const type = typeof attrs.type === \"string\" ? attrs.type : \"install\";\n const dev = attrs.dev === true || attrs.dev === \"true\";\n\n let commands: string[];\n if (type === \"run\") {\n const command = args ?? \"dev\";\n commands = [\n `npm run ${command}`,\n `pnpm ${command}`,\n `yarn ${command}`,\n `bun run ${command}`,\n ];\n } else if (type === \"exec\") {\n const command = args ?? pkg ?? \"\";\n commands = [\n `npx ${command}`,\n `pnpm exec ${command}`,\n `yarn exec ${command}`,\n `bunx ${command}`,\n ];\n } else if (type === \"dlx\") {\n const command = args ?? pkg ?? \"\";\n commands = [\n `npx ${command}`,\n `pnpm dlx ${command}`,\n `yarn dlx ${command}`,\n `bunx ${command}`,\n ];\n } else if (pkg) {\n commands = [\n `npm install ${dev ? \"--save-dev \" : \"\"}${pkg}`,\n `pnpm add ${dev ? \"-D \" : \"\"}${pkg}`,\n `yarn add ${dev ? \"-D \" : \"\"}${pkg}`,\n `bun add ${dev ? \"-d \" : \"\"}${pkg}`,\n ];\n } else {\n return \"\";\n }\n\n return [\"```sh\", ...commands, \"```\"].join(\"\\n\");\n}\n\nfunction applyDefaultComponentTransforms(markdown: string): string {\n let out = markdown;\n\n out = out.replace(\n /<PackageManagers\\b([^>]*)\\/>/g,\n (_match, rawAttrs: string) => renderPackageManagers(parseAttrs(rawAttrs)),\n );\n\n out = out.replace(\n /<Aside\\b([^>]*)>([\\s\\S]*?)<\\/Aside>/g,\n (_match, rawAttrs: string, children: string) => {\n const attrs = parseAttrs(rawAttrs);\n const type = asTitle(attrs.type, \"note\").toUpperCase();\n const title = asTitle(attrs.title, type.charAt(0) + type.slice(1).toLowerCase());\n const body = cleanChildren(children);\n return blockquote(`**${title}**\\n\\n${body}`);\n },\n );\n\n out = out.replace(\n /<Card\\b([^>]*)>([\\s\\S]*?)<\\/Card>/g,\n (_match, rawAttrs: string, children: string) => {\n const attrs = parseAttrs(rawAttrs);\n const title = asTitle(attrs.title, \"Card\");\n const body = cleanChildren(children);\n return `- **${title}**${body ? ` — ${body}` : \"\"}`;\n },\n );\n out = out.replace(/<\\/?CardGrid\\b[^>]*>/g, \"\");\n\n out = out.replace(/<Steps\\b[^>]*>([\\s\\S]*?)<\\/Steps>/g, (_match, children: string) => {\n let index = 0;\n return children.replace(\n /<Step\\b([^>]*)>([\\s\\S]*?)<\\/Step>/g,\n (_stepMatch, rawAttrs: string, stepChildren: string) => {\n index += 1;\n const attrs = parseAttrs(rawAttrs);\n const title = asTitle(attrs.title, `Step ${index}`);\n const body = cleanChildren(stepChildren);\n return `${index}. **${title}**${body ? `\\n\\n ${body.replace(/\\n/g, \"\\n \")}` : \"\"}`;\n },\n );\n });\n\n out = out.replace(/<Tabs\\b[^>]*>([\\s\\S]*?)<\\/Tabs>/g, (_match, children: string) =>\n children.replace(\n /<TabItem\\b([^>]*)>([\\s\\S]*?)<\\/TabItem>/g,\n (_tabMatch, rawAttrs: string, tabChildren: string) => {\n const attrs = parseAttrs(rawAttrs);\n const label = asTitle(attrs.label, \"Option\");\n return `### ${label}\\n\\n${cleanChildren(tabChildren)}`;\n },\n ),\n );\n\n // If user content includes raw component wrappers we don't know about,\n // preserve their children rather than leaking JSX into the markdown.\n out = out.replace(/<([A-Z][A-Za-z0-9]*)\\b[^>]*>([\\s\\S]*?)<\\/\\1>/g, \"$2\");\n out = out.replace(/<([A-Z][A-Za-z0-9]*)\\b[^>]*\\/>/g, \"\");\n\n return out;\n}\n\nfunction applyCustomComponentTransforms(\n markdown: string,\n componentMap: Record<string, MarkdownComponentRenderer>,\n): string {\n let out = markdown;\n for (const [name, render] of Object.entries(componentMap)) {\n const paired = new RegExp(`<${name}\\\\b([^>]*)>([\\\\s\\\\S]*?)<\\\\/${name}>`, \"g\");\n out = out.replace(paired, (_match, rawAttrs: string, children: string) =>\n render({ name, attrs: parseAttrs(rawAttrs), children: cleanChildren(children) }),\n );\n\n const selfClosing = new RegExp(`<${name}\\\\b([^>]*)\\\\/>`, \"g\");\n out = out.replace(selfClosing, (_match, rawAttrs: string) =>\n render({ name, attrs: parseAttrs(rawAttrs), children: \"\" }),\n );\n }\n return out;\n}\n\n/**\n * Render an Astro content entry's raw MDX body as plain markdown.\n *\n * This handles the starter's default MDX components. Users can pass a\n * `componentMap` to override individual component renderers or replace this\n * function entirely from their user-owned `.md` route.\n */\nexport function renderEntryAsMarkdown(\n entry: MarkdownEntry,\n options: RenderEntryAsMarkdownOptions = {},\n): string {\n const stripFrontmatter = options.stripFrontmatter ?? true;\n let markdown = entry.body ?? \"\";\n\n if (stripFrontmatter) {\n markdown = markdown.replace(/^---\\n[\\s\\S]*?\\n---\\n?/, \"\");\n }\n\n const protectedCode = protectCode(markdown);\n markdown = protectedCode.markdown;\n\n if (options.componentMap) {\n markdown = applyCustomComponentTransforms(markdown, options.componentMap);\n }\n markdown = applyDefaultComponentTransforms(markdown);\n markdown = protectedCode.restore(markdown);\n\n return markdown\n .replace(/^[ \\t]+(- \\*\\*)/gm, \"$1\")\n .replace(/^[ \\t]+(\\d+\\. \\*\\*)/gm, \"$1\")\n .replace(/^[ \\t]+(### )/gm, \"$1\")\n .replace(/^[ \\t]+(```)/gm, \"$1\")\n .replace(/^[ \\t]+$/gm, \"\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n","import type { Breadcrumb, PrevNext, PrevNextOverrides, SidebarItem } from \"../types.js\";\nimport { flattenSidebar } from \"./sidebar.js\";\n\nexport type { Breadcrumb, PrevNext, PrevNextOverrides };\n\nexport function getBreadcrumbs(slug: string, homeLabel = \"Home\"): Breadcrumb[] {\n const parts = slug.split(\"/\").filter(Boolean);\n const crumbs: Breadcrumb[] = [{ label: homeLabel, href: \"/\" }];\n\n let path = \"\";\n for (const part of parts) {\n path += `/${part}`;\n crumbs.push({\n label: part.replace(/-/g, \" \").replace(/\\b\\w/g, (c) => c.toUpperCase()),\n href: path,\n });\n }\n\n return crumbs;\n}\n\ntype PrevNextOverride = { link?: string; label?: string };\n\nfunction normalizeInternalPath(path: string): string {\n const [withoutHash] = path.split(\"#\", 1);\n const [pathname] = withoutHash.split(\"?\", 1);\n return pathname || \"/\";\n}\n\nfunction resolveOverride(\n override: string | PrevNextOverride | false | undefined,\n fallback: { label: string; href: string } | undefined,\n validInternalLinks?: Set<string>,\n): { label: string; href: string } | undefined {\n if (override === false) return undefined;\n if (override === undefined) return fallback;\n if (typeof override === \"string\") {\n // String form: label-only override — keeps the sidebar neighbor's href, replaces the label\n if (!fallback) return undefined;\n return { label: override, href: fallback.href };\n }\n // Object form: merge with fallback — omitted fields inherit from sidebar neighbor\n if (override.link && !override.link.startsWith(\"/\") && !override.link.startsWith(\"http\")) {\n throw new Error(\n `prev/next override link \"${override.link}\" must be an absolute path (starting with /) or a full URL`,\n );\n }\n if (override.link?.startsWith(\"/\") && validInternalLinks) {\n const targetPath = normalizeInternalPath(override.link);\n if (!validInternalLinks.has(targetPath)) {\n throw new Error(`prev/next override link \"${override.link}\" does not match any existing internal docs route`);\n }\n }\n const label = override.label ?? fallback?.label;\n const href = override.link ?? fallback?.href;\n\n // Without a sidebar neighbor, object overrides must be complete.\n if (!fallback && (label === undefined || href === undefined)) {\n throw new Error(\"prev/next object override requires both `label` and `link` when no sidebar neighbor exists\");\n }\n\n if (!href) return undefined;\n return { label: label ?? \"\", href };\n}\n\nexport function getPrevNext(\n currentPath: string,\n sidebarTree: SidebarItem[],\n overrides?: PrevNextOverrides,\n validInternalLinks?: Set<string>,\n): PrevNext {\n const flat = flattenSidebar(sidebarTree);\n const index = flat.findIndex((item) => item.href === currentPath);\n\n const sidebarPrev = index > 0 ? { label: flat[index - 1].label, href: flat[index - 1].href! } : undefined;\n const sidebarNext =\n index >= 0 && index < flat.length - 1 ? { label: flat[index + 1].label, href: flat[index + 1].href! } : undefined;\n\n if (!overrides) {\n return { prev: sidebarPrev, next: sidebarNext };\n }\n\n return {\n prev: resolveOverride(overrides.prev, sidebarPrev, validInternalLinks),\n next: resolveOverride(overrides.next, sidebarNext, validInternalLinks),\n };\n}\n","import type { TOCItem } from \"../types.js\";\n\nexport interface TocConfig {\n minHeadingLevel?: number;\n maxHeadingLevel?: number;\n}\n\nexport function getHeadings(\n headings: { depth: number; text: string; slug: string }[],\n config?: TocConfig,\n): TOCItem[] {\n const min = config?.minHeadingLevel ?? 2;\n const max = config?.maxHeadingLevel ?? 3;\n return headings.filter((h) => h.depth >= min && h.depth <= max);\n}\n","/**\n * git-last-updated.ts — Derive a per-page `lastUpdated` from `git log`.\n *\n * Uses the **author date** (`%aI`) instead of the committer date (`%cI`)\n * so the value stays stable when a branch is rebased: rebases rewrite\n * commit dates but preserve author dates for unchanged content. Squash\n * merges produce a single new commit that touches the file, so the\n * date naturally reflects the squash moment — which is the right answer\n * for \"when did this content last change in the published history.\"\n *\n * Returns `undefined` on every failure mode so the caller can fall back\n * cleanly to frontmatter (or render nothing):\n *\n * - `git` not on PATH (CI image without git, container without it)\n * - File isn't tracked yet (new content in a draft branch, untracked)\n * - Repo is a shallow clone / partial clone and the file's history\n * isn't in the local pack (Vercel default `fetch-depth: 1`,\n * Cloudflare Pages similar). Users who want git-derived dates in\n * production should set `fetch-depth: 0` on `actions/checkout` or\n * equivalent.\n * - Process isn't inside a git working tree at all\n *\n * Results are cached per-process. A typical docs build calls this once\n * per entry; the cache prevents redundant subprocess spawns when the\n * same entry's filePath shows up across multiple pages (e.g. sidebar\n * preview, full render).\n */\n\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\nconst cache = new Map<string, Date | undefined>();\n\n/**\n * Run `git log -1 --format=%aI -- <filePath>` and parse the result as a\n * `Date`. Returns `undefined` on any error or empty result.\n *\n * Pass either the entry's `filePath` (Astro provides this on every\n * content entry) or an explicit relative path. Relative paths resolve\n * against the current working directory (Astro builds run from the\n * project root, which is inside the git repo).\n */\nexport async function getLastUpdatedFromGit(\n filePath: string,\n): Promise<Date | undefined> {\n if (!filePath) return undefined;\n if (cache.has(filePath)) return cache.get(filePath);\n\n let result: Date | undefined;\n try {\n const { stdout } = await execFileAsync(\n \"git\",\n [\"log\", \"-1\", \"--format=%aI\", \"--\", filePath],\n // No `cwd` override — Astro runs from the project root which is\n // inside the repo. Git itself walks upward to find `.git`.\n { windowsHide: true },\n );\n const trimmed = stdout.trim();\n if (trimmed) {\n const parsed = new Date(trimmed);\n // Guard against `new Date(\"\")` → Invalid Date that still passes\n // `instanceof Date`. `getTime()` returns NaN for invalid dates.\n if (!Number.isNaN(parsed.getTime())) {\n result = parsed;\n }\n }\n } catch {\n // Swallow: caller falls back to frontmatter or renders no date.\n result = undefined;\n }\n\n cache.set(filePath, result);\n return result;\n}\n","/**\n * Extract registered MDX global names from the user's `src/components.ts`.\n *\n * The framework needs this list to validate PascalCase tags in MDX at\n * build time, but it must not execute user code at build time. Strategy:\n * read the file as text, locate the `export const components = { ... }`\n * declaration, and parse its top-level keys.\n *\n * Supported entry shapes inside the object literal:\n * - shorthand: `Foo,` → \"Foo\"\n * - aliased: `Foo: Other,` → \"Foo\" (the key)\n * - string key: `\"Foo\": Other,` → \"Foo\"\n *\n * Skipped (no false-positive failures):\n * - spread elements (`...other`)\n * - computed keys (`[expr]: value`)\n * - lowercase keys (not PascalCase, so not validator-relevant)\n *\n * Returns:\n * - `string[]` of registered names when the file exists and the pattern\n * matches.\n * - `null` when the file is missing OR present but doesn't expose a\n * parseable `export const components = { ... }`. The caller decides\n * whether to warn or skip validation.\n */\n\nimport fs from \"node:fs/promises\";\n\nconst EXPORT_PATTERN =\n /export\\s+const\\s+components\\s*(?::\\s*[^=]+)?=\\s*\\{([\\s\\S]*?)\\n\\s*\\}\\s*(?:as\\s+const)?\\s*;?/;\n\nexport async function parseComponentsRegistry(\n filePath: string,\n): Promise<string[] | null> {\n let source: string;\n try {\n source = await fs.readFile(filePath, \"utf8\");\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw err;\n }\n\n const match = source.match(EXPORT_PATTERN);\n if (!match) return null;\n\n // Strip line + block comments so commas inside `// foo, bar` don't split.\n const body = match[1]\n .replace(/\\/\\/[^\\n]*/g, \"\")\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\");\n\n const names: string[] = [];\n for (const raw of splitTopLevelCommas(body)) {\n const entry = raw.trim();\n if (!entry) continue;\n if (entry.startsWith(\"...\")) continue;\n if (entry.startsWith(\"[\")) continue;\n\n const colonIdx = entry.indexOf(\":\");\n const rawKey = colonIdx === -1 ? entry : entry.slice(0, colonIdx);\n const key = rawKey.trim().replace(/^['\"`]|['\"`]$/g, \"\");\n\n if (/^[A-Z][A-Za-z0-9_]*$/.test(key)) names.push(key);\n }\n\n return names;\n}\n\n/**\n * Split a string on commas that are at depth 0 (not inside `{}`, `[]`,\n * `()`, or string literals). Required because object entries can themselves\n * contain commas (e.g. `Foo: bar({ a: 1, b: 2 })`).\n */\nfunction splitTopLevelCommas(input: string): string[] {\n const result: string[] = [];\n let depth = 0;\n let start = 0;\n let inString: string | null = null;\n\n for (let i = 0; i < input.length; i++) {\n const ch = input[i];\n if (inString) {\n if (ch === \"\\\\\") {\n i++;\n continue;\n }\n if (ch === inString) inString = null;\n continue;\n }\n if (ch === '\"' || ch === \"'\" || ch === \"`\") inString = ch;\n else if (ch === \"{\" || ch === \"[\" || ch === \"(\") depth++;\n else if (ch === \"}\" || ch === \"]\" || ch === \")\") depth--;\n else if (ch === \",\" && depth === 0) {\n result.push(input.slice(start, i));\n start = i + 1;\n }\n }\n result.push(input.slice(start));\n return result;\n}\n","/**\n * code-transformers.ts — Shiki transformer chain used both by the\n * markdown pipeline (registered into `shikiConfig.transformers` from\n * the Astro integration so fenced MDX blocks pick them up) and by the\n * user's `<Code>` component (Astro's built-in `<Code>` accepts\n * `transformers` as a prop but does *not* auto-read `shikiConfig`).\n *\n * The single source of truth lives here so both paths get the same\n * polish — diff, highlight, focus, error-level, word-highlight, plus\n * meta line/word highlight from `@shikijs/transformers`, plus the\n * Nimbus-owned `titleAndLangTransformer` that:\n *\n * - Wraps the rendered `<pre>` in a `<figure class=\"nb-code-figure\">`\n * whenever the fenced block has `title=\"...\"` in its meta. The\n * figure carries a `<figcaption class=\"nb-code-title\">` with the\n * filename and a small language tag at the right end.\n * - Always tags the `<pre>` with `data-nb-lang=\"…\"` so the starter\n * CSS can render a top-right language badge on un-titled blocks.\n */\n\nimport type { ShikiTransformer } from \"shiki\";\nimport {\n transformerNotationDiff,\n transformerNotationFocus,\n transformerNotationHighlight,\n transformerNotationErrorLevel,\n transformerNotationWordHighlight,\n transformerMetaHighlight,\n transformerMetaWordHighlight,\n} from \"@shikijs/transformers\";\n\n/**\n * Parse Shiki meta string (the bit after the language fence:\n * ```ts title=\"src/foo.ts\" {1,3}`) for the `title=\"...\"` key.\n * Returns `undefined` when the meta has no title.\n */\nfunction parseTitle(meta: string | undefined): string | undefined {\n if (!meta) return undefined;\n const match = meta.match(/\\btitle=\"([^\"]+)\"/) ?? meta.match(/\\btitle='([^']+)'/);\n return match?.[1];\n}\n\n/**\n * The canonical Shiki transformer chain for Nimbus. Returns a fresh\n * array each call so callers don't accidentally mutate a shared list.\n *\n * Used by:\n * - `integration.ts` → `shikiConfig.transformers` (fenced MDX blocks)\n * - `Code.astro` in the starter → `transformers` prop on Astro's\n * built-in `<Code>` component (and by extension, anything that\n * composes `<Code>` such as `<CodeGroup>`)\n */\nexport function defaultCodeTransformers(): ShikiTransformer[] {\n return [\n transformerNotationDiff(),\n transformerNotationHighlight(),\n transformerNotationFocus(),\n transformerNotationErrorLevel(),\n transformerNotationWordHighlight(),\n transformerMetaHighlight(),\n transformerMetaWordHighlight(),\n titleAndLangTransformer(),\n ];\n}\n\nexport function titleAndLangTransformer(): ShikiTransformer {\n return {\n name: \"nimbus:title-and-lang\",\n pre(preNode) {\n const lang = this.options.lang || \"text\";\n const meta: string | undefined = (this.options.meta as { __raw?: string } | undefined)?.__raw;\n const title = parseTitle(meta);\n\n // Always tag the pre with its language for CSS.\n preNode.properties = preNode.properties ?? {};\n preNode.properties[\"data-nb-lang\"] = lang;\n\n if (!title) return preNode;\n\n // Wrap in a <figure> with a <figcaption> header bar.\n return {\n type: \"element\",\n tagName: \"figure\",\n properties: {\n class: \"nb-code-figure\",\n \"data-nb-lang\": lang,\n },\n children: [\n {\n type: \"element\",\n tagName: \"figcaption\",\n properties: { class: \"nb-code-title\" },\n children: [\n {\n type: \"element\",\n tagName: \"span\",\n properties: { class: \"nb-code-title-name\" },\n children: [{ type: \"text\", value: title }],\n },\n {\n type: \"element\",\n tagName: \"span\",\n properties: { class: \"nb-code-title-lang\" },\n children: [{ type: \"text\", value: lang }],\n },\n ],\n },\n preNode,\n ],\n };\n },\n };\n}\n","/**\n * Tiny Levenshtein distance + \"did you mean\" suggester.\n *\n * Used by the MDX PascalCase validator and any framework diagnostic that\n * wants to suggest a near-match on a misspelled name. Kept internal — user\n * code that wants the same hint duplicates ~10 lines rather than depending\n * on a framework wrapper. See the north-star guardrail on thin wrappers.\n */\n\nexport function levenshtein(a: string, b: string): number {\n if (a === b) return 0;\n if (a.length === 0) return b.length;\n if (b.length === 0) return a.length;\n const v0 = new Array<number>(b.length + 1);\n const v1 = new Array<number>(b.length + 1);\n for (let i = 0; i <= b.length; i++) v0[i] = i;\n for (let i = 0; i < a.length; i++) {\n v1[0] = i + 1;\n for (let j = 0; j < b.length; j++) {\n const cost = a[i] === b[j] ? 0 : 1;\n v1[j + 1] = Math.min(v1[j] + 1, v0[j + 1] + 1, v0[j] + cost);\n }\n for (let j = 0; j <= b.length; j++) v0[j] = v1[j];\n }\n return v1[b.length];\n}\n\n/**\n * Return the closest candidate within `maxDist`, or null.\n *\n * Comparison is case-insensitive (so \"tabs\" suggests \"Tabs\"), but the\n * returned name keeps its original casing.\n */\nexport function suggest(\n target: string,\n candidates: Iterable<string>,\n maxDist = 3,\n): string | null {\n const targetLower = target.toLowerCase();\n let best: { name: string; dist: number } | null = null;\n for (const c of candidates) {\n const dist = levenshtein(targetLower, c.toLowerCase());\n if (dist <= maxDist && (!best || dist < best.dist)) {\n best = { name: c, dist };\n }\n }\n return best?.name ?? null;\n}\n","/**\n * MDX PascalCase tag validator — runs as a content pass, not a remark\n * plugin, so it works regardless of which markdown processor the user\n * has wired into `markdown.processor` (Sätteri replaces unified's\n * pipeline, which silently disables remark plugins attached via\n * `mdx({ remarkPlugins })`).\n *\n * Strategy:\n *\n * 1. Walk the configured content directories for `.mdx` files.\n * 2. For each file: split frontmatter, parse imports + JSX tags from\n * the body, validate every PascalCase tag against globals + per-file\n * imports.\n * 3. Collect every failure across every file (don't fail-fast), then\n * throw one error with all locations and \"did you mean\" hints.\n *\n * Parsing approach is intentionally regex-based and not a full MDX\n * parser. Tradeoffs:\n *\n * - Pro: zero MDX/remark deps, runs in milliseconds, no pipeline\n * coupling. Survives processor swaps (satteri / unified / future).\n * - Pro: tolerates malformed MDX — the validator's job is to find\n * unknown tags, not to be the parser of record.\n * - Con: a few edge cases (JSX inside string literals inside expression\n * children, deeply nested fenced code with `~~~`) can produce false\n * positives. Code blocks (``` and indented) are stripped before\n * scanning to keep the common case clean.\n *\n * Catches the silent-failure case where MDX renders unknown PascalCase\n * tags as literal text on the deployed page — the bug appears in\n * production, not in the build log.\n */\n\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { suggest } from \"./levenshtein.js\";\n\nexport interface ValidateMdxContentOptions {\n /** Names available globally (from `src/components.ts`). */\n globals: ReadonlyArray<string>;\n /**\n * Absolute paths to scan. Typically `[<projectRoot>/src/content]`.\n * Each path is walked recursively for `.mdx` files.\n */\n contentDirs: ReadonlyArray<string>;\n /**\n * Optional filter to skip files (e.g. vendored MDX). Receives the\n * absolute path; return `true` to skip validation.\n */\n skip?: (filePath: string) => boolean;\n /**\n * Project root, used to print file paths relative to it in error\n * messages. Falls back to the absolute path when not provided.\n */\n projectRoot?: string;\n}\n\nexport interface ValidationFailure {\n filePath: string;\n tag: string;\n line: number;\n column: number;\n hint: string | null;\n}\n\nexport async function validateMdxContent(\n options: ValidateMdxContentOptions,\n): Promise<ValidationFailure[]> {\n const globalsSet = new Set(options.globals);\n const failures: ValidationFailure[] = [];\n\n for (const dir of options.contentDirs) {\n const files = await walkMdx(dir);\n for (const file of files) {\n if (options.skip?.(file)) continue;\n const source = await fs.readFile(file, \"utf8\");\n const fileFailures = scanFile(source, globalsSet);\n for (const f of fileFailures) {\n const knownNames = [...globalsSet, ...f.imports];\n failures.push({\n filePath: options.projectRoot\n ? path.relative(options.projectRoot, file)\n : file,\n tag: f.tag,\n line: f.line,\n column: f.column,\n hint: suggest(f.tag, knownNames),\n });\n }\n }\n }\n\n return failures;\n}\n\n/**\n * Format a list of failures into a single multi-line error message\n * suitable for `throw new Error(...)`.\n */\nexport function formatFailures(\n failures: ReadonlyArray<ValidationFailure>,\n globalsCount: number,\n): string {\n const lines = failures.map((f) => {\n const fix = f.hint\n ? `Did you mean <${f.hint} />?`\n : globalsCount === 0\n ? `Register it in src/components.ts, or add an explicit \\`import\\` at the top of this file.`\n : `Register it in src/components.ts, or add an explicit \\`import\\` at the top of this file.`;\n return ` ${f.filePath}:${f.line}:${f.column} <${f.tag} /> → ${fix}`;\n });\n\n const noun = failures.length === 1 ? \"tag\" : \"tags\";\n return (\n `[nimbus-docs] Unknown MDX component ${noun}:\\n` +\n lines.join(\"\\n\") +\n `\\n\\nA PascalCase tag in MDX must either be registered in src/components.ts (the global registry) or imported at the top of the file. ` +\n `Without either, MDX renders the tag as literal text on the page — a silent failure this validator turns into a build error.`\n );\n}\n\n// ---------------------------------------------------------------------------\n// File walking\n// ---------------------------------------------------------------------------\n\nasync function walkMdx(dir: string): Promise<string[]> {\n const out: string[] = [];\n async function visit(current: string) {\n let entries: import(\"node:fs\").Dirent[];\n try {\n entries = await fs.readdir(current, { withFileTypes: true });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return;\n throw err;\n }\n for (const entry of entries) {\n const full = path.join(current, entry.name);\n if (entry.isDirectory()) {\n if (entry.name === \"node_modules\" || entry.name.startsWith(\".\")) continue;\n await visit(full);\n } else if (entry.isFile() && entry.name.endsWith(\".mdx\")) {\n out.push(full);\n }\n }\n }\n await visit(dir);\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Per-file scanner\n// ---------------------------------------------------------------------------\n\ninterface RawFailure {\n tag: string;\n line: number;\n column: number;\n imports: Set<string>;\n}\n\nfunction scanFile(\n source: string,\n globalsSet: ReadonlySet<string>,\n): RawFailure[] {\n const { body, bodyOffset } = stripFrontmatter(source);\n const imports = parseImports(body);\n const stripped = stripCodeBlocks(body);\n const tags = findPascalCaseTags(stripped);\n\n const failures: RawFailure[] = [];\n for (const tag of tags) {\n if (globalsSet.has(tag.name) || imports.has(tag.name)) continue;\n const position = absolutePosition(source, bodyOffset + tag.offset);\n failures.push({\n tag: tag.name,\n line: position.line,\n column: position.column,\n imports,\n });\n }\n return failures;\n}\n\nfunction stripFrontmatter(source: string): { body: string; bodyOffset: number } {\n const match = source.match(/^---\\n[\\s\\S]*?\\n---\\n?/);\n if (!match) return { body: source, bodyOffset: 0 };\n return { body: source.slice(match[0].length), bodyOffset: match[0].length };\n}\n\n/**\n * Extract names introduced by top-level `import` statements. Handles\n * default, named (with optional aliases), and namespace imports.\n */\nfunction parseImports(body: string): Set<string> {\n const names = new Set<string>();\n // Match `import ... from \"...\"` and side-effect `import \"...\"` (no names).\n const importPattern = /^\\s*import\\s+([^\"';]+?)\\s+from\\s+[\"'][^\"']+[\"']\\s*;?/gm;\n for (const match of body.matchAll(importPattern)) {\n const clause = match[1];\n // Namespace: `import * as Foo from \"...\"`\n const namespaceMatch = clause.match(/\\*\\s+as\\s+([A-Za-z_$][\\w$]*)/);\n if (namespaceMatch) {\n names.add(namespaceMatch[1]);\n continue;\n }\n // Strip and split: `Default, { Named, Aliased as Local }`\n const beforeBrace = clause.split(\"{\")[0].trim().replace(/,\\s*$/, \"\");\n if (beforeBrace && /^[A-Za-z_$][\\w$]*$/.test(beforeBrace)) {\n names.add(beforeBrace);\n }\n const braceMatch = clause.match(/\\{([^}]*)\\}/);\n if (braceMatch) {\n for (const raw of braceMatch[1].split(\",\")) {\n const spec = raw.trim();\n if (!spec) continue;\n const aliasMatch = spec.match(/^[A-Za-z_$][\\w$]*\\s+as\\s+([A-Za-z_$][\\w$]*)$/);\n if (aliasMatch) {\n names.add(aliasMatch[1]);\n } else if (/^[A-Za-z_$][\\w$]*$/.test(spec)) {\n names.add(spec);\n }\n }\n }\n }\n return names;\n}\n\n/**\n * Remove fenced code blocks and inline code spans so JSX-looking text\n * inside code samples doesn't trip the validator.\n */\nfunction stripCodeBlocks(body: string): string {\n return body\n .replace(/```[\\s\\S]*?```/g, (m) => \" \".repeat(m.length))\n .replace(/~~~[\\s\\S]*?~~~/g, (m) => \" \".repeat(m.length))\n .replace(/`[^`\\n]*`/g, (m) => \" \".repeat(m.length));\n}\n\ninterface FoundTag {\n name: string;\n offset: number;\n}\n\n/**\n * Find PascalCase JSX-like tags. Matches `<Capital...` at the start of\n * an element (opening or self-closing). Closing tags `</Capital>` and\n * JSX fragments `<>` are not counted (the opener already covers\n * registration; counting closers would double-report).\n */\nfunction findPascalCaseTags(body: string): FoundTag[] {\n const out: FoundTag[] = [];\n const pattern = /<([A-Z][A-Za-z0-9_]*)\\b/g;\n for (const match of body.matchAll(pattern)) {\n out.push({ name: match[1], offset: match.index ?? 0 });\n }\n return out;\n}\n\n/**\n * Compute 1-based line + column for an absolute character offset in the\n * original source.\n */\nfunction absolutePosition(source: string, offset: number): { line: number; column: number } {\n let line = 1;\n let column = 1;\n const end = Math.min(offset, source.length);\n for (let i = 0; i < end; i++) {\n if (source[i] === \"\\n\") {\n line++;\n column = 1;\n } else {\n column++;\n }\n }\n return { line, column };\n}\n","/**\n * Config validation.\n *\n * Errors target content authors, not framework developers.\n * Astro 6 ships Zod v4 via `astro/zod` — single `error` field, not v3 patterns.\n */\n\nimport { z } from \"astro/zod\";\nimport type { NimbusConfig } from \"../types.js\";\n\nconst headElementSchema = z.object({\n tag: z.enum([\"meta\", \"link\", \"script\", \"style\"]),\n attrs: z.record(z.string(), z.string()).default({}),\n content: z.string().optional(),\n});\n\nconst featuresSchema = z\n .object({\n search: z.boolean().default(true),\n editLinks: z.boolean().default(true),\n pagination: z.boolean().default(true),\n toc: z.boolean().default(true),\n })\n .default({ search: true, editLinks: true, pagination: true, toc: true });\n\nconst searchSchema = z\n .union([\n z.literal(false),\n z.object({\n provider: z.enum([\"pagefind\", \"custom\"]).default(\"pagefind\"),\n }),\n ])\n .optional();\n\n// Sidebar items are intentionally loose — the sidebar builder accepts the\n// shapes documented in types.ts; tightening here adds friction for users\n// without catching real errors that the builder doesn't already catch.\nconst sidebarSchema = z\n .object({\n items: z.array(z.unknown()).optional(),\n })\n .passthrough()\n .optional();\n\nconst nimbusConfigSchema = z.object({\n site: z.string().url({ message: '\"site\" must be a valid URL' }),\n title: z.string(),\n description: z.string().optional(),\n logo: z.string().max(2),\n locale: z.string().default(\"en\"),\n homeLabel: z.string().default(\"Home\"),\n github: z.string().url().nullable().default(null),\n // editPattern must contain the `{path}` placeholder. Without it,\n // `getEditUrl()` returns the pattern unchanged for every entry — a\n // silent footgun that ships broken edit links to production.\n editPattern: z\n .string()\n .nullable()\n .default(null)\n .refine((v) => v === null || v.includes(\"{path}\"), {\n message:\n '\"editPattern\" must contain the \"{path}\" placeholder, which is replaced with the entry source path. ' +\n 'Example: \"https://github.com/my-org/my-repo/edit/main/{path}\"',\n }),\n footer: z.string().default(\"Built with Nimbus\"),\n socialImage: z\n .string({ error: '\"socialImage\" must be a string (path or URL)' })\n .optional(),\n socialImageAlt: z\n .string({ error: '\"socialImageAlt\" must be a string' })\n .optional(),\n head: z.array(headElementSchema).default([]),\n sidebar: sidebarSchema,\n features: featuresSchema,\n search: searchSchema,\n});\n\nexport function validateNimbusConfig(input: unknown): NimbusConfig {\n const result = nimbusConfigSchema.safeParse(input);\n if (result.success) {\n return result.data as NimbusConfig;\n }\n\n // Build a content-author-readable issue list. Each line carries:\n // - the dotted config path (so it's greppable in nimbus.config.ts)\n // - the validator message\n // - the offending value (truncated) when one was supplied\n const issues = result.error.issues\n .map((issue) => {\n // Zod v4 widens path entries to PropertyKey. Symbols never appear in\n // our schema (no symbol keys), so it's safe to coerce to string|number\n // for both display and value lookup.\n const issuePath = issue.path\n .filter((p): p is string | number => typeof p !== \"symbol\");\n const display = issuePath.length > 0 ? issuePath.join(\".\") : \"(root)\";\n const received = formatReceived(input, issuePath);\n const tail = received === null ? \"\" : `\\n received: ${received}`;\n return ` - ${display}: ${issue.message}${tail}`;\n })\n .join(\"\\n\");\n\n throw new Error(\n `Invalid nimbus.config — fix these issues:\\n${issues}\\n\\n` +\n `See https://nimbus-docs.dev/config for the full config schema.`,\n );\n}\n\n/**\n * Resolve the value at `path` inside the raw input and format it for an\n * error message. Returns null when the path is unreachable (e.g. a\n * required key is missing entirely — in that case the message itself\n * already says \"Required\", so we don't double up).\n */\nfunction formatReceived(input: unknown, path: ReadonlyArray<string | number>): string | null {\n let cursor: unknown = input;\n for (const key of path) {\n if (cursor === null || typeof cursor !== \"object\") return null;\n cursor = (cursor as Record<string | number, unknown>)[key];\n if (cursor === undefined) return null;\n }\n if (cursor === undefined) return null;\n try {\n const json = JSON.stringify(cursor);\n if (json === undefined) return String(cursor);\n return json.length > 120 ? `${json.slice(0, 117)}...` : json;\n } catch {\n return String(cursor);\n }\n}\n","/**\n * Vite plugin: exposes the validated NimbusConfig via `virtual:nimbus/config`.\n *\n * Consumers in user-land:\n *\n * import { config } from \"virtual:nimbus/config\";\n *\n * Used by data helpers (getSidebar, getPrevNext, etc.) so they don't need\n * the config passed at every call site.\n */\n\nimport type { NimbusConfig } from \"../types.js\";\n\nconst VIRTUAL_ID = \"virtual:nimbus/config\";\nconst RESOLVED_ID = `\\0${VIRTUAL_ID}`;\n\nexport interface VitePluginLike {\n name: string;\n resolveId(id: string): string | undefined;\n load(id: string): string | undefined;\n}\n\nexport function virtualConfigPlugin(config: NimbusConfig): VitePluginLike {\n return {\n name: \"nimbus-docs:virtual-config\",\n resolveId(id: string) {\n if (id === VIRTUAL_ID) return RESOLVED_ID;\n return undefined;\n },\n load(id: string) {\n if (id === RESOLVED_ID) {\n return `export const config = ${JSON.stringify(config)};\\n`;\n }\n return undefined;\n },\n };\n}\n","/**\n * The Nimbus Astro integration.\n *\n * Responsibilities:\n * - Validate the user-supplied config (throws on invalid input).\n * - Bridge `nimbusConfig.site` → Astro's top-level `site` so the\n * sitemap integration and `Astro.site` read from one source.\n * - Register `@astrojs/mdx` and `@astrojs/sitemap`.\n * - Install the Sätteri markdown processor — handles heading slugs +\n * ships with built-in Shiki dual-theme highlighting (configured via\n * Astro's `markdown.shikiConfig`).\n * - Build-time MDX PascalCase tag validation against the user's\n * `src/components.ts` registry plus per-file imports. Catches the\n * silent-failure case where MDX renders an unknown PascalCase tag\n * as literal text on the deployed site. Opt out via\n * `validateMdx: false`.\n * - Expose validated config via `virtual:nimbus/config`.\n * - Inject TypeScript types for the virtual module so consumers get\n * intellisense without manual ambient declarations.\n *\n * Not framework territory (the user's `content.config.ts` owns these):\n * - Content collection registration. The user imports\n * `docsCollection()` / `partialsCollection()` from\n * `nimbus-docs/content` and registers them themselves.\n * - MDX globals injection. The user passes `components={components}`\n * when rendering `<Content />`.\n *\n * Planned (not shipped):\n * - `/llms.txt` and `/robots.txt` route injection.\n */\n\nimport { execFile } from \"node:child_process\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { AstroIntegration } from \"astro\";\nimport mdx from \"@astrojs/mdx\";\nimport { satteri } from \"@astrojs/markdown-satteri\";\nimport sitemap from \"@astrojs/sitemap\";\nimport { parseComponentsRegistry } from \"./_internal/parse-components-registry.js\";\nimport { defaultCodeTransformers } from \"./_internal/code-transformers.js\";\nimport {\n formatFailures,\n validateMdxContent,\n} from \"./_internal/validate-mdx-content.js\";\nimport { validateNimbusConfig } from \"./_internal/validate.js\";\nimport { virtualConfigPlugin } from \"./_internal/virtual-config.js\";\nimport type { NimbusConfig } from \"./types.js\";\n\nexport interface NimbusIntegrationOptions {\n /** MDX options forwarded to `@astrojs/mdx`. */\n mdx?: Parameters<typeof mdx>[0];\n /** Skip sitemap integration. Default: enabled when `site.url` is set. */\n sitemap?: boolean;\n /**\n * Build-time MDX PascalCase tag validation.\n *\n * - `true` (default): parse `src/components.ts` for the globals\n * registry and fail the build on unknown PascalCase tags found\n * in `src/content/**\\/*.mdx`.\n * - `false`: skip validation entirely.\n * - `{ componentsPath }`: override the registry file location.\n * Relative paths resolve to the project root.\n * - `{ contentDirs }`: override the scanned directories. Relative\n * paths resolve to the project root. Default: `[\"src/content\"]`.\n * - `{ skip }`: filter out files (e.g. vendored or generated MDX).\n *\n * Runs as a pre-build content pass rather than as a remark plugin so\n * it works regardless of which markdown processor is wired into\n * `markdown.processor`. Sätteri (the default) replaces unified's\n * pipeline, which silently disables remark plugins attached via\n * `mdx({ remarkPlugins })`.\n */\n validateMdx?:\n | boolean\n | {\n componentsPath?: string;\n contentDirs?: string[];\n skip?: (filePath: string) => boolean;\n };\n}\n\nexport function nimbus(\n rawConfig: NimbusConfig,\n options: NimbusIntegrationOptions = {},\n): AstroIntegration {\n const config = validateNimbusConfig(rawConfig);\n\n return {\n name: \"nimbus-docs\",\n hooks: {\n \"astro:config:setup\": async (params) => {\n const { updateConfig, config: astroConfig, logger } = params;\n\n const integrationsToAdd: AstroIntegration[] = [];\n\n // Pre-build MDX validation. Runs as a content pass against\n // `src/content/**/*.mdx` rather than as a remark plugin —\n // Sätteri replaces unified's pipeline and silently disables\n // any remark plugins, so the per-file-during-compile path is\n // not reliable here.\n if (options.validateMdx !== false) {\n const validateOpts =\n typeof options.validateMdx === \"object\" ? options.validateMdx : {};\n const projectRoot = fileURLToPath(astroConfig.root);\n const componentsPath = path.isAbsolute(validateOpts.componentsPath ?? \"\")\n ? (validateOpts.componentsPath as string)\n : path.join(\n projectRoot,\n validateOpts.componentsPath ?? \"src/components.ts\",\n );\n\n const globals = await parseComponentsRegistry(componentsPath);\n if (globals === null) {\n logger.warn(\n `MDX validation disabled: \\`${path.relative(projectRoot, componentsPath)}\\` is missing or does not export a parseable \\`components\\` object. ` +\n `Create the file with \\`export const components = { /* ... */ };\\` or set \\`validateMdx: false\\` to silence this warning.`,\n );\n } else {\n const contentDirs = (validateOpts.contentDirs ?? [\"src/content\"]).map(\n (d) => (path.isAbsolute(d) ? d : path.join(projectRoot, d)),\n );\n const failures = await validateMdxContent({\n globals,\n contentDirs,\n skip: validateOpts.skip,\n projectRoot,\n });\n if (failures.length > 0) {\n throw new Error(formatFailures(failures, globals.length));\n }\n logger.info(\n `MDX validation passed — ${globals.length} global component${globals.length === 1 ? \"\" : \"s\"} registered, ${contentDirs.length} content dir${contentDirs.length === 1 ? \"\" : \"s\"} scanned.`,\n );\n }\n }\n\n // MDX is always added; sitemap only when `site` is configured.\n integrationsToAdd.push(mdx(options.mdx ?? {}));\n if (options.sitemap !== false && Boolean(config.site)) {\n integrationsToAdd.push(sitemap());\n }\n\n updateConfig({\n // Bridge `nimbusConfig.site` → Astro's top-level `site`. The\n // sitemap integration and `Astro.site` both read this; without\n // it, sitemap warns \"missing `site` astro.config option\" at\n // build time even though nimbus has a site URL right there.\n // Only set when configured (validate.ts already enforces it,\n // but stay defensive for future optionality).\n ...(config.site ? { site: config.site } : {}),\n // Astro deep-merges arrays in updateConfig, so user-declared\n // integrations are preserved.\n integrations: integrationsToAdd,\n // Sätteri markdown processor. Heading IDs, image collection,\n // and Shiki highlighting are all wired internally by Sätteri's\n // default plugin set — no manual registration needed. MDX\n // inherits via @astrojs/mdx's `extendMarkdownConfig: true`.\n markdown: {\n processor: satteri(),\n // Dual-theme Shiki output. `defaultColor: false` makes Shiki\n // emit BOTH themes as inline CSS variables (`--shiki-light`,\n // `--shiki-dark`, `--shiki-light-bg`, `--shiki-dark-bg`)\n // rather than baking one theme into the HTML. The starter's\n // globals.css then switches between them based on the\n // `<html data-mode=\"dark\">` attribute the theme toggle flips.\n //\n // `defaultCodeTransformers()` is the single source of truth\n // for the premium code-block features — diff/highlight/focus/\n // error/word notations, meta highlight, and the title-frame +\n // lang badge transformer. The same factory is exported as a\n // named entry from `nimbus-docs` so the starter's `Code.astro`\n // can wire them into Astro's built-in `<Code>` component\n // (Astro's `<Code>` doesn't auto-read `shikiConfig`).\n //\n // Users can override these defaults by passing their own\n // shikiConfig at the user-config level (Astro merges shallowly).\n shikiConfig: {\n themes: {\n light: \"github-light\",\n dark: \"github-dark\",\n },\n defaultColor: false,\n transformers: defaultCodeTransformers(),\n },\n },\n // Vite plugin exposing the validated config to user-land via\n // the `virtual:nimbus/config` import.\n vite: {\n plugins: [virtualConfigPlugin(config)],\n },\n });\n },\n \"astro:config:done\": ({ injectTypes }) => {\n // TypeScript declaration for the virtual module. Written to\n // `.astro/integrations/nimbus-docs/virtual-config.d.ts` and\n // auto-referenced by the project tsconfig via Astro's generated\n // types.\n injectTypes({\n filename: \"virtual-config.d.ts\",\n content: [\n 'declare module \"virtual:nimbus/config\" {',\n ' import type { NimbusConfig } from \"nimbus-docs/types\";',\n \" export const config: NimbusConfig;\",\n \"}\",\n \"\",\n ].join(\"\\n\"),\n });\n },\n \"astro:build:done\": async ({ dir }) => {\n if (config.search === false || config.search?.provider === \"custom\") {\n return;\n }\n\n await runPagefind(fileURLToPath(dir));\n },\n },\n };\n}\n\nfunction runPagefind(siteDir: string): Promise<void> {\n const bin = process.platform === \"win32\" ? \"pagefind.cmd\" : \"pagefind\";\n return new Promise((resolve) => {\n execFile(bin, [\"--site\", siteDir], (error, stdout, stderr) => {\n if (stdout) process.stdout.write(stdout);\n if (stderr) process.stderr.write(stderr);\n if (error) {\n console.warn(\n `[nimbus-docs] Pagefind did not run. Install pagefind as a devDependency or set search: false in your Nimbus config.\\n${error.message}`,\n );\n }\n resolve();\n });\n });\n}\n","/**\n * Main entry for `nimbus-docs`.\n *\n * Exports the Astro integration (default), config helper, and the four\n * data helpers (sidebar, prev/next, breadcrumbs, TOC). Phase 6 will\n * add page composition helpers (`getDocsStaticPaths`, `getDocsPageProps`).\n *\n * Helpers read the user's config from `virtual:nimbus/config` (provided\n * by our Vite plugin) and content entries from `astro:content`. Both\n * are external in tsdown and resolved at the consumer's build time.\n */\n\nimport { loadNimbusConfig } from \"./_internal/runtime-config.js\";\nimport {\n getVisibleEntries,\n getVisibleEntriesByCollection,\n} from \"./_internal/content.js\";\nimport {\n buildSidebarTree,\n collectSidebarCollectionRefs,\n deriveSidebarSections,\n scopeToCurrentSection,\n sidebarHash,\n} from \"./_internal/sidebar.js\";\nimport { renderEntryAsMarkdown } from \"./_internal/transform.js\";\n\n/** Primary collection name — kept in sync with `_internal/content.ts`. */\nconst PRIMARY_COLLECTION = \"docs\";\nimport {\n getBreadcrumbs as buildBreadcrumbs,\n getPrevNext as buildPrevNext,\n} from \"./_internal/navigation.js\";\nimport { getHeadings } from \"./_internal/toc.js\";\nimport { getLastUpdatedFromGit } from \"./_internal/git-last-updated.js\";\n\nimport type {\n Breadcrumb,\n NimbusConfig,\n PrevNext,\n PrevNextOverrides,\n SidebarItem,\n SidebarSection,\n TOCItem,\n} from \"./types.js\";\n\nexport { nimbus as default } from \"./integration.js\";\nexport type { NimbusIntegrationOptions } from \"./integration.js\";\n\nexport type {\n BadgeVariant,\n Breadcrumb,\n NimbusConfig,\n PrevNext,\n PrevNextLink,\n PrevNextOverrides,\n SearchProvider,\n SearchResult,\n SidebarBadge,\n SidebarConfig,\n SidebarConfigItem,\n SidebarExternalLinkItem,\n SidebarGroupItem,\n SidebarItem,\n SidebarLinkItem,\n SidebarSection,\n TOCItem,\n} from \"./types.js\";\n\n/**\n * Define a typed Nimbus config. Returns the config unchanged but inferred.\n */\nexport function defineConfig<T extends NimbusConfig>(config: T): T {\n return config;\n}\n\n/** Deterministic short hash of the sidebar structure (for sessionStorage invalidation). */\nexport { sidebarHash };\n\n/** Render an Astro content entry's raw MDX body as clean markdown. */\nexport { renderEntryAsMarkdown };\n\n/**\n * The canonical Shiki transformer chain — diff / highlight / focus /\n * error-level / word notations, meta highlight, plus the title-frame +\n * language-badge transformer. Pre-wired into the markdown pipeline for\n * fenced MDX blocks; re-export it so `Code.astro` can pass the same\n * list to Astro's built-in `<Code>` component (which accepts\n * `transformers` as a prop but doesn't auto-read `shikiConfig`).\n */\nexport { defaultCodeTransformers } from \"./_internal/code-transformers.js\";\n\n/**\n * Return visible entries across the user's configured `collections`.\n * Drafts are filtered in production builds. Pass an explicit\n * `collections` argument to scope the query to a subset.\n *\n * Replaces the old `getVisibleDocs()` — same draft-filtering semantics,\n * but now collection-aware. Returns `CollectionEntry<string>[]` so\n * cross-collection traversal doesn't need per-name type narrowing.\n */\nexport { getVisibleEntries };\n\n// ---------------------------------------------------------------------------\n// Data helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Build the sidebar tree for the given current path, scoped to the\n * top-level section containing that page.\n *\n * Reads `sidebar` from the user's nimbus.config. If `sidebar.items` is set,\n * resolves config-driven sidebar. Otherwise auto-generates from filesystem\n * (i.e. the `docs` collection's entry IDs).\n *\n * The returned tree is always scoped: only the current section's children\n * are returned. To enumerate every top-level section (for header tabs or\n * a section switcher), use `getSidebarSections`.\n *\n * @param currentSlug - The current page's URL path (e.g. \"/getting-started\").\n * Used to set `isCurrent` on matching links and to pick\n * which top-level section to surface.\n */\nexport async function getSidebar(currentSlug: string): Promise<SidebarItem[]> {\n const tree = await buildFullSidebarTree(currentSlug);\n return scopeToCurrentSection(tree, currentSlug);\n}\n\n/**\n * Derive one section per top-level group in the sidebar — used by\n * `Header.astro` to render the section tab strip (and by any other\n * cross-section navigation).\n *\n * Reads the un-scoped tree so every section is visible, then collapses\n * each top-level group to `{ label, href, isActive }`.\n */\nexport async function getSidebarSections(currentSlug: string): Promise<SidebarSection[]> {\n const tree = await buildFullSidebarTree(currentSlug);\n return deriveSidebarSections(tree);\n}\n\n/**\n * Internal: build the un-scoped sidebar tree. Shared by `getSidebar` and\n * `getSidebarSections`.\n */\nasync function buildFullSidebarTree(currentSlug: string): Promise<SidebarItem[]> {\n const runtimeConfig = await loadNimbusConfig();\n // Collections to load are derived from sidebar items: always the\n // primary (`docs`) plus any extra collection named by an\n // `autogenerate: { collection }` reference. No separate config list.\n const referenced = collectSidebarCollectionRefs(runtimeConfig.sidebar?.items);\n const collections = [\n PRIMARY_COLLECTION,\n ...referenced.filter((c) => c !== PRIMARY_COLLECTION),\n ];\n const entriesByCollection = await getVisibleEntriesByCollection(collections);\n return buildSidebarTree(\n entriesByCollection,\n PRIMARY_COLLECTION,\n currentSlug,\n runtimeConfig.sidebar,\n );\n}\n\n/**\n * Resolve prev/next links for the current page.\n *\n * Walks the flattened sidebar; returns the surrounding entries. Honors\n * `prev`/`next` frontmatter overrides if provided.\n */\nexport async function getPrevNext(\n currentSlug: string,\n options?: {\n overrides?: PrevNextOverrides;\n sidebarTree?: SidebarItem[];\n },\n): Promise<PrevNext> {\n const tree = options?.sidebarTree ?? (await getSidebar(currentSlug));\n return buildPrevNext(currentSlug, tree, options?.overrides);\n}\n\n/**\n * Build breadcrumb trail from \"/\" to the current page.\n *\n * Phase 5: simple URL-segment derivation. Later phases may enrich with\n * sidebar-aware labels.\n */\nexport async function getBreadcrumbs(\n currentSlug: string,\n options?: { homeLabel?: string },\n): Promise<Breadcrumb[]> {\n return buildBreadcrumbs(currentSlug, options?.homeLabel ?? \"Home\");\n}\n\n/**\n * Build an edit URL for a content entry using `config.editPattern`.\n *\n * `{path}` is replaced with the entry's source path when Astro provides it,\n * falling back to the default docs collection path convention.\n */\nexport async function getEditUrl(entry: {\n id: string;\n filePath?: string;\n}): Promise<string | undefined> {\n const runtimeConfig = await loadNimbusConfig();\n if (!runtimeConfig.editPattern) return undefined;\n\n const path = entry.filePath ?? `src/content/docs/${entry.id}.mdx`;\n return runtimeConfig.editPattern.replace(\"{path}\", path);\n}\n\n/**\n * Resolve a content entry's `lastUpdated` date from `git log`.\n *\n * Reads the author date (`%aI`) of the most recent commit that touched\n * the entry's source file. Author date is stable across rebases — the\n * value reflects when the content was actually changed, not when the\n * commit happened to land in this branch.\n *\n * Returns `undefined` when git can't answer (no `.git`, shallow clone,\n * file untracked, command not on PATH, etc.) so the caller can chain a\n * fallback:\n *\n * const lastUpdated = entry.data.lastUpdated ?? await getLastUpdated(entry);\n *\n * Frontmatter always wins. Per-process cached so repeated calls for\n * the same entry don't re-spawn `git`.\n *\n * Production note: most CI/CD systems do shallow clones by default\n * (Vercel, Cloudflare Pages, GitHub Actions checkout@v4) — set\n * `fetch-depth: 0` to make full history available, otherwise git\n * returns nothing and the helper falls back to frontmatter or nothing.\n */\nexport async function getLastUpdated(entry: {\n id: string;\n filePath?: string;\n}): Promise<Date | undefined> {\n const path = entry.filePath ?? `src/content/docs/${entry.id}.mdx`;\n return getLastUpdatedFromGit(path);\n}\n\n/**\n * Filter heading list to the configured min/max heading levels.\n *\n * @param headings - Raw `headings` from Astro's `render(entry)` return value.\n * @param options - Override min/max heading levels. Defaults: min=2, max=3.\n */\nexport function getTOC(\n headings: { depth: number; text: string; slug: string }[],\n options?: { minHeadingLevel?: number; maxHeadingLevel?: number },\n): TOCItem[] {\n return getHeadings(headings, options);\n}\n\n// ---------------------------------------------------------------------------\n// Page composition helpers\n// ---------------------------------------------------------------------------\n\nimport type { AstroGlobal, GetStaticPaths } from \"astro\";\n\n/**\n * `getStaticPaths` implementation for a docs catch-all route.\n *\n * Returns one path per visible entry in the `docs` collection. Drafts are\n * filtered in production. Each path passes `{ entry }` as props so the\n * page component can access it via `getDocsPageProps(Astro)`.\n *\n * Usage:\n *\n * // src/pages/[...slug].astro\n * export const prerender = true;\n * export const getStaticPaths = getDocsStaticPaths;\n *\n * The entry's `id` is used verbatim as the slug. So `docs/index.mdx` →\n * `/index`, `docs/guides/setup.mdx` → `/guides/setup`. If you want a docs\n * entry at the root URL, name it appropriately and decide whether to use\n * a static `pages/index.astro` or let the catch-all handle root.\n */\nexport const getDocsStaticPaths: GetStaticPaths = async () => {\n // Docs-specific helper: always reads the `docs` collection. Other\n // collections require their own `pages/<name>/[...slug].astro` with\n // a one-line `getCollection(\"<name>\")`-based getStaticPaths.\n const entries = await getVisibleEntries([\"docs\"]);\n return entries.map((entry) => ({\n params: { slug: entry.id },\n props: { entry },\n }));\n};\n\n/**\n * Read the current entry from `Astro.props`, render it, and return the\n * pieces a docs page needs: the typed entry, the renderable `<Content />`\n * component, and the headings list (for TOC generation).\n *\n * Pass the page's `Astro` global. Throws if `Astro.props.entry` is missing,\n * which indicates the page didn't wire `getDocsStaticPaths` (or a custom\n * equivalent) correctly.\n *\n * Usage:\n *\n * const { entry, Content, headings } = await getDocsPageProps(Astro);\n */\nexport async function getDocsPageProps(astro: AstroGlobal): Promise<{\n entry: import(\"astro:content\").CollectionEntry<\"docs\">;\n Content: unknown;\n headings: { depth: number; text: string; slug: string }[];\n}> {\n const entry = (astro.props as { entry?: import(\"astro:content\").CollectionEntry<\"docs\"> })\n .entry;\n if (!entry) {\n throw new Error(\n \"getDocsPageProps(): expected `entry` in Astro.props. \" +\n \"Ensure your route uses `getStaticPaths = getDocsStaticPaths` \" +\n \"(or passes an entry via custom getStaticPaths).\",\n );\n }\n const { render } = await import(\"astro:content\");\n const { Content, headings } = await render(entry);\n return { entry, Content, headings };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
//#region src/lib/pkgm.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Package-manager command translator.
|
|
4
|
+
*
|
|
5
|
+
* Maps a logical command (`install`, `add`, `dlx`, etc.) plus optional
|
|
6
|
+
* package name and flags to the appropriate command string for npm,
|
|
7
|
+
* pnpm, yarn, and bun. Pure data + a string-builder — runs at build
|
|
8
|
+
* time in Astro frontmatter, not in the browser.
|
|
9
|
+
*
|
|
10
|
+
* Currently consumed by the PackageManagers component. Free-standing —
|
|
11
|
+
* customize freely or use elsewhere; you own this code.
|
|
12
|
+
*/
|
|
13
|
+
type Manager = "npm" | "yarn" | "pnpm" | "bun";
|
|
14
|
+
type CommandType = "add" | "create" | "dlx" | "exec" | "install" | "remove" | "run";
|
|
15
|
+
interface CommandOptions {
|
|
16
|
+
args?: string;
|
|
17
|
+
dev?: boolean;
|
|
18
|
+
comment?: string;
|
|
19
|
+
}
|
|
20
|
+
interface GetTabsOptions extends CommandOptions {
|
|
21
|
+
/**
|
|
22
|
+
* Restrict to a subset of managers. Defaults to all known: npm, yarn,
|
|
23
|
+
* pnpm, bun. Order in the array determines tab order.
|
|
24
|
+
*
|
|
25
|
+
* getTabs("install", "astro", { managers: ["npm", "pnpm"] });
|
|
26
|
+
*/
|
|
27
|
+
managers?: readonly Manager[];
|
|
28
|
+
}
|
|
29
|
+
declare const MANAGERS: readonly Manager[];
|
|
30
|
+
declare function getCommand(mgr: Manager, type: CommandType, pkg?: string, {
|
|
31
|
+
args,
|
|
32
|
+
dev,
|
|
33
|
+
comment
|
|
34
|
+
}?: CommandOptions): string | undefined;
|
|
35
|
+
declare function getTabs(type: CommandType, pkg?: string, options?: GetTabsOptions): {
|
|
36
|
+
mgr: Manager;
|
|
37
|
+
cmd: string;
|
|
38
|
+
}[];
|
|
39
|
+
//#endregion
|
|
40
|
+
export { CommandOptions, CommandType, GetTabsOptions, MANAGERS, Manager, getCommand, getTabs };
|
|
41
|
+
//# sourceMappingURL=pkgm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pkgm.d.ts","names":[],"sources":["../../src/lib/pkgm.ts"],"mappings":";;AAYA;;;;;AAEA;;;;;KAFY,OAAA;AAAA,KAEA,WAAA;AAAA,UASK,cAAA;EACf,IAAA;EACA,GAAA;EACA,OAAA;AAAA;AAAA,UAGe,cAAA,SAAuB,cAAA;EAH/B;AAGT;;;;;EAOE,QAAA,YAAoB,OAAA;AAAA;AAAA,cAiDT,QAAA,WAAmB,OAAA;AAAA,iBAEhB,UAAA,CACd,GAAA,EAAK,OAAA,EACL,IAAA,EAAM,WAAA,EACN,GAAA;EACE,IAAA;EAAM,GAAA;EAAa;AAAA,IAAW,cAAA;AAAA,iBAmBlB,OAAA,CACd,IAAA,EAAM,WAAA,EACN,GAAA,WACA,OAAA,GAAS,cAAA;EACN,GAAA,EAAK,OAAA;EAAS,GAAA;AAAA"}
|
package/dist/lib/pkgm.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
//#region src/lib/pkgm.ts
|
|
2
|
+
const commands = {
|
|
3
|
+
npm: {
|
|
4
|
+
add: "npm i",
|
|
5
|
+
create: "npm create",
|
|
6
|
+
dlx: "npx",
|
|
7
|
+
exec: "npx",
|
|
8
|
+
install: "npm install",
|
|
9
|
+
run: "npm run",
|
|
10
|
+
remove: "npm uninstall",
|
|
11
|
+
dev: "-D"
|
|
12
|
+
},
|
|
13
|
+
yarn: {
|
|
14
|
+
add: "yarn add",
|
|
15
|
+
create: "yarn create",
|
|
16
|
+
dlx: "yarn dlx",
|
|
17
|
+
exec: "yarn",
|
|
18
|
+
install: "yarn install",
|
|
19
|
+
run: "yarn run",
|
|
20
|
+
remove: "yarn remove",
|
|
21
|
+
dev: "-D"
|
|
22
|
+
},
|
|
23
|
+
pnpm: {
|
|
24
|
+
add: "pnpm add",
|
|
25
|
+
create: "pnpm create",
|
|
26
|
+
dlx: "pnpm dlx",
|
|
27
|
+
exec: "pnpm",
|
|
28
|
+
install: "pnpm install",
|
|
29
|
+
run: "pnpm run",
|
|
30
|
+
remove: "pnpm remove",
|
|
31
|
+
dev: "-D"
|
|
32
|
+
},
|
|
33
|
+
bun: {
|
|
34
|
+
add: "bun add",
|
|
35
|
+
create: "bun create",
|
|
36
|
+
dlx: "bunx",
|
|
37
|
+
exec: "bunx",
|
|
38
|
+
install: "bun install",
|
|
39
|
+
run: "bun run",
|
|
40
|
+
remove: "bun remove",
|
|
41
|
+
dev: "-d"
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
const MANAGERS = [
|
|
45
|
+
"npm",
|
|
46
|
+
"yarn",
|
|
47
|
+
"pnpm",
|
|
48
|
+
"bun"
|
|
49
|
+
];
|
|
50
|
+
function getCommand(mgr, type, pkg, { args, dev = false, comment } = {}) {
|
|
51
|
+
let cmd = commands[mgr][type];
|
|
52
|
+
if (cmd === void 0) return void 0;
|
|
53
|
+
if (comment) cmd = `# ${comment}\n${cmd}`;
|
|
54
|
+
if (dev && type === "add") cmd += ` ${commands[mgr].dev}`;
|
|
55
|
+
if (pkg) {
|
|
56
|
+
const processedPkg = type === "create" && mgr === "yarn" ? pkg.replace(/@(?![^@]*\/)[^\s]*$/, "") : pkg;
|
|
57
|
+
cmd += ` ${processedPkg}`;
|
|
58
|
+
}
|
|
59
|
+
if (args) cmd += `${mgr === "npm" && ![
|
|
60
|
+
"dlx",
|
|
61
|
+
"exec",
|
|
62
|
+
"run"
|
|
63
|
+
].includes(type) ? " --" : ""} ${args}`;
|
|
64
|
+
return cmd;
|
|
65
|
+
}
|
|
66
|
+
function getTabs(type, pkg, options = {}) {
|
|
67
|
+
const { managers, ...commandOptions } = options;
|
|
68
|
+
return (managers ?? MANAGERS).filter((mgr) => commands[mgr][type] !== void 0).map((mgr) => ({
|
|
69
|
+
mgr,
|
|
70
|
+
cmd: getCommand(mgr, type, pkg, commandOptions)
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
//#endregion
|
|
75
|
+
export { MANAGERS, getCommand, getTabs };
|
|
76
|
+
//# sourceMappingURL=pkgm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pkgm.js","names":[],"sources":["../../src/lib/pkgm.ts"],"sourcesContent":["/**\n * Package-manager command translator.\n *\n * Maps a logical command (`install`, `add`, `dlx`, etc.) plus optional\n * package name and flags to the appropriate command string for npm,\n * pnpm, yarn, and bun. Pure data + a string-builder — runs at build\n * time in Astro frontmatter, not in the browser.\n *\n * Currently consumed by the PackageManagers component. Free-standing —\n * customize freely or use elsewhere; you own this code.\n */\n\nexport type Manager = \"npm\" | \"yarn\" | \"pnpm\" | \"bun\";\n\nexport type CommandType =\n | \"add\"\n | \"create\"\n | \"dlx\"\n | \"exec\"\n | \"install\"\n | \"remove\"\n | \"run\";\n\nexport interface CommandOptions {\n args?: string;\n dev?: boolean;\n comment?: string;\n}\n\nexport interface GetTabsOptions extends CommandOptions {\n /**\n * Restrict to a subset of managers. Defaults to all known: npm, yarn,\n * pnpm, bun. Order in the array determines tab order.\n *\n * getTabs(\"install\", \"astro\", { managers: [\"npm\", \"pnpm\"] });\n */\n managers?: readonly Manager[];\n}\n\nconst commands: Record<\n Manager,\n Partial<Record<CommandType, string>> & { dev: string }\n> = {\n npm: {\n add: \"npm i\",\n create: \"npm create\",\n dlx: \"npx\",\n exec: \"npx\",\n install: \"npm install\",\n run: \"npm run\",\n remove: \"npm uninstall\",\n dev: \"-D\",\n },\n yarn: {\n add: \"yarn add\",\n create: \"yarn create\",\n dlx: \"yarn dlx\",\n exec: \"yarn\",\n install: \"yarn install\",\n run: \"yarn run\",\n remove: \"yarn remove\",\n dev: \"-D\",\n },\n pnpm: {\n add: \"pnpm add\",\n create: \"pnpm create\",\n dlx: \"pnpm dlx\",\n exec: \"pnpm\",\n install: \"pnpm install\",\n run: \"pnpm run\",\n remove: \"pnpm remove\",\n dev: \"-D\",\n },\n bun: {\n add: \"bun add\",\n create: \"bun create\",\n dlx: \"bunx\",\n exec: \"bunx\",\n install: \"bun install\",\n run: \"bun run\",\n remove: \"bun remove\",\n dev: \"-d\",\n },\n};\n\nexport const MANAGERS: readonly Manager[] = [\"npm\", \"yarn\", \"pnpm\", \"bun\"];\n\nexport function getCommand(\n mgr: Manager,\n type: CommandType,\n pkg?: string,\n { args, dev = false, comment }: CommandOptions = {},\n): string | undefined {\n let cmd = commands[mgr][type];\n if (cmd === undefined) return undefined;\n if (comment) cmd = `# ${comment}\\n${cmd}`;\n if (dev && type === \"add\") cmd += ` ${commands[mgr].dev}`;\n if (pkg) {\n const processedPkg =\n type === \"create\" && mgr === \"yarn\"\n ? pkg.replace(/@(?![^@]*\\/)[^\\s]*$/, \"\")\n : pkg;\n cmd += ` ${processedPkg}`;\n }\n if (args) {\n cmd += `${mgr === \"npm\" && ![\"dlx\", \"exec\", \"run\"].includes(type) ? \" --\" : \"\"} ${args}`;\n }\n return cmd;\n}\n\nexport function getTabs(\n type: CommandType,\n pkg?: string,\n options: GetTabsOptions = {},\n): { mgr: Manager; cmd: string }[] {\n const { managers, ...commandOptions } = options;\n const list = managers ?? MANAGERS;\n return list\n .filter((mgr) => commands[mgr][type] !== undefined)\n .map((mgr) => ({\n mgr,\n cmd: getCommand(mgr, type, pkg, commandOptions)!,\n }));\n}\n"],"mappings":";AAuCA,MAAM,WAGF;CACF,KAAK;EACH,KAAK;EACL,QAAQ;EACR,KAAK;EACL,MAAM;EACN,SAAS;EACT,KAAK;EACL,QAAQ;EACR,KAAK;EACN;CACD,MAAM;EACJ,KAAK;EACL,QAAQ;EACR,KAAK;EACL,MAAM;EACN,SAAS;EACT,KAAK;EACL,QAAQ;EACR,KAAK;EACN;CACD,MAAM;EACJ,KAAK;EACL,QAAQ;EACR,KAAK;EACL,MAAM;EACN,SAAS;EACT,KAAK;EACL,QAAQ;EACR,KAAK;EACN;CACD,KAAK;EACH,KAAK;EACL,QAAQ;EACR,KAAK;EACL,MAAM;EACN,SAAS;EACT,KAAK;EACL,QAAQ;EACR,KAAK;EACN;CACF;AAED,MAAa,WAA+B;CAAC;CAAO;CAAQ;CAAQ;CAAM;AAE1E,SAAgB,WACd,KACA,MACA,KACA,EAAE,MAAM,MAAM,OAAO,YAA4B,EAAE,EAC/B;CACpB,IAAI,MAAM,SAAS,KAAK;AACxB,KAAI,QAAQ,OAAW,QAAO;AAC9B,KAAI,QAAS,OAAM,KAAK,QAAQ,IAAI;AACpC,KAAI,OAAO,SAAS,MAAO,QAAO,IAAI,SAAS,KAAK;AACpD,KAAI,KAAK;EACP,MAAM,eACJ,SAAS,YAAY,QAAQ,SACzB,IAAI,QAAQ,uBAAuB,GAAG,GACtC;AACN,SAAO,IAAI;;AAEb,KAAI,KACF,QAAO,GAAG,QAAQ,SAAS,CAAC;EAAC;EAAO;EAAQ;EAAM,CAAC,SAAS,KAAK,GAAG,QAAQ,GAAG,GAAG;AAEpF,QAAO;;AAGT,SAAgB,QACd,MACA,KACA,UAA0B,EAAE,EACK;CACjC,MAAM,EAAE,UAAU,GAAG,mBAAmB;AAExC,SADa,YAAY,UAEtB,QAAQ,QAAQ,SAAS,KAAK,UAAU,OAAU,CAClD,KAAK,SAAS;EACb;EACA,KAAK,WAAW,KAAK,MAAM,KAAK,eAAe;EAChD,EAAE"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { z } from "astro/zod";
|
|
2
|
+
|
|
3
|
+
//#region src/schemas.d.ts
|
|
4
|
+
interface DocSchemaConfig {
|
|
5
|
+
/** Additional frontmatter fields merged into the default schema. */
|
|
6
|
+
fields?: Record<string, z.ZodTypeAny>;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Build a customizable docs schema. Use this when composing schemas outside
|
|
10
|
+
* the `docsCollection()` factory (e.g. multiple docs collections with
|
|
11
|
+
* different shapes).
|
|
12
|
+
*/
|
|
13
|
+
declare function defineDocSchema(config?: DocSchemaConfig): z.ZodObject<{
|
|
14
|
+
title: z.ZodString;
|
|
15
|
+
description: z.ZodOptional<z.ZodString>;
|
|
16
|
+
template: z.ZodDefault<z.ZodEnum<{
|
|
17
|
+
doc: "doc";
|
|
18
|
+
splash: "splash";
|
|
19
|
+
}>>;
|
|
20
|
+
sidebar: z.ZodOptional<z.ZodObject<{
|
|
21
|
+
order: z.ZodOptional<z.ZodNumber>;
|
|
22
|
+
label: z.ZodOptional<z.ZodString>;
|
|
23
|
+
badge: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
24
|
+
text: z.ZodString;
|
|
25
|
+
variant: z.ZodDefault<z.ZodEnum<{
|
|
26
|
+
success: "success";
|
|
27
|
+
default: "default";
|
|
28
|
+
info: "info";
|
|
29
|
+
note: "note";
|
|
30
|
+
tip: "tip";
|
|
31
|
+
warning: "warning";
|
|
32
|
+
caution: "caution";
|
|
33
|
+
danger: "danger";
|
|
34
|
+
}>>;
|
|
35
|
+
}, z.core.$strip>]>>;
|
|
36
|
+
hidden: z.ZodOptional<z.ZodBoolean>;
|
|
37
|
+
hideChildren: z.ZodOptional<z.ZodBoolean>;
|
|
38
|
+
}, z.core.$strip>>;
|
|
39
|
+
hero: z.ZodOptional<z.ZodObject<{
|
|
40
|
+
title: z.ZodOptional<z.ZodString>;
|
|
41
|
+
tagline: z.ZodOptional<z.ZodString>;
|
|
42
|
+
actions: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
43
|
+
text: z.ZodString;
|
|
44
|
+
link: z.ZodString;
|
|
45
|
+
variant: z.ZodDefault<z.ZodEnum<{
|
|
46
|
+
primary: "primary";
|
|
47
|
+
secondary: "secondary";
|
|
48
|
+
outline: "outline";
|
|
49
|
+
}>>;
|
|
50
|
+
icon: z.ZodOptional<z.ZodString>;
|
|
51
|
+
}, z.core.$strip>>>;
|
|
52
|
+
}, z.core.$strip>>;
|
|
53
|
+
head: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
54
|
+
tag: z.ZodEnum<{
|
|
55
|
+
link: "link";
|
|
56
|
+
meta: "meta";
|
|
57
|
+
script: "script";
|
|
58
|
+
style: "style";
|
|
59
|
+
}>;
|
|
60
|
+
attrs: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
61
|
+
content: z.ZodOptional<z.ZodString>;
|
|
62
|
+
}, z.core.$strip>>>;
|
|
63
|
+
draft: z.ZodDefault<z.ZodBoolean>;
|
|
64
|
+
noindex: z.ZodDefault<z.ZodBoolean>;
|
|
65
|
+
llms: z.ZodDefault<z.ZodBoolean>;
|
|
66
|
+
aiDeprioritize: z.ZodDefault<z.ZodBoolean>;
|
|
67
|
+
pagefind: z.ZodDefault<z.ZodBoolean>;
|
|
68
|
+
tableOfContents: z.ZodOptional<z.ZodObject<{
|
|
69
|
+
minHeadingLevel: z.ZodDefault<z.ZodNumber>;
|
|
70
|
+
maxHeadingLevel: z.ZodDefault<z.ZodNumber>;
|
|
71
|
+
}, z.core.$strip>>;
|
|
72
|
+
lastUpdated: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
73
|
+
socialImage: z.ZodOptional<z.ZodString>;
|
|
74
|
+
prev: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
75
|
+
link: z.ZodOptional<z.ZodString>;
|
|
76
|
+
label: z.ZodOptional<z.ZodString>;
|
|
77
|
+
}, z.core.$strip>, z.ZodLiteral<false>]>>;
|
|
78
|
+
next: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
79
|
+
link: z.ZodOptional<z.ZodString>;
|
|
80
|
+
label: z.ZodOptional<z.ZodString>;
|
|
81
|
+
}, z.core.$strip>, z.ZodLiteral<false>]>>;
|
|
82
|
+
}, z.core.$strip> | z.ZodObject<{
|
|
83
|
+
[x: string]: z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
|
|
84
|
+
}, z.core.$strip>;
|
|
85
|
+
/** Default docs schema. Equivalent to `defineDocSchema()`. */
|
|
86
|
+
declare const docsSchema: z.ZodObject<{
|
|
87
|
+
title: z.ZodString;
|
|
88
|
+
description: z.ZodOptional<z.ZodString>;
|
|
89
|
+
template: z.ZodDefault<z.ZodEnum<{
|
|
90
|
+
doc: "doc";
|
|
91
|
+
splash: "splash";
|
|
92
|
+
}>>;
|
|
93
|
+
sidebar: z.ZodOptional<z.ZodObject<{
|
|
94
|
+
order: z.ZodOptional<z.ZodNumber>;
|
|
95
|
+
label: z.ZodOptional<z.ZodString>;
|
|
96
|
+
badge: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
97
|
+
text: z.ZodString;
|
|
98
|
+
variant: z.ZodDefault<z.ZodEnum<{
|
|
99
|
+
success: "success";
|
|
100
|
+
default: "default";
|
|
101
|
+
info: "info";
|
|
102
|
+
note: "note";
|
|
103
|
+
tip: "tip";
|
|
104
|
+
warning: "warning";
|
|
105
|
+
caution: "caution";
|
|
106
|
+
danger: "danger";
|
|
107
|
+
}>>;
|
|
108
|
+
}, z.core.$strip>]>>;
|
|
109
|
+
hidden: z.ZodOptional<z.ZodBoolean>;
|
|
110
|
+
hideChildren: z.ZodOptional<z.ZodBoolean>;
|
|
111
|
+
}, z.core.$strip>>;
|
|
112
|
+
hero: z.ZodOptional<z.ZodObject<{
|
|
113
|
+
title: z.ZodOptional<z.ZodString>;
|
|
114
|
+
tagline: z.ZodOptional<z.ZodString>;
|
|
115
|
+
actions: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
116
|
+
text: z.ZodString;
|
|
117
|
+
link: z.ZodString;
|
|
118
|
+
variant: z.ZodDefault<z.ZodEnum<{
|
|
119
|
+
primary: "primary";
|
|
120
|
+
secondary: "secondary";
|
|
121
|
+
outline: "outline";
|
|
122
|
+
}>>;
|
|
123
|
+
icon: z.ZodOptional<z.ZodString>;
|
|
124
|
+
}, z.core.$strip>>>;
|
|
125
|
+
}, z.core.$strip>>;
|
|
126
|
+
head: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
127
|
+
tag: z.ZodEnum<{
|
|
128
|
+
link: "link";
|
|
129
|
+
meta: "meta";
|
|
130
|
+
script: "script";
|
|
131
|
+
style: "style";
|
|
132
|
+
}>;
|
|
133
|
+
attrs: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
134
|
+
content: z.ZodOptional<z.ZodString>;
|
|
135
|
+
}, z.core.$strip>>>;
|
|
136
|
+
draft: z.ZodDefault<z.ZodBoolean>;
|
|
137
|
+
noindex: z.ZodDefault<z.ZodBoolean>;
|
|
138
|
+
llms: z.ZodDefault<z.ZodBoolean>;
|
|
139
|
+
aiDeprioritize: z.ZodDefault<z.ZodBoolean>;
|
|
140
|
+
pagefind: z.ZodDefault<z.ZodBoolean>;
|
|
141
|
+
tableOfContents: z.ZodOptional<z.ZodObject<{
|
|
142
|
+
minHeadingLevel: z.ZodDefault<z.ZodNumber>;
|
|
143
|
+
maxHeadingLevel: z.ZodDefault<z.ZodNumber>;
|
|
144
|
+
}, z.core.$strip>>;
|
|
145
|
+
lastUpdated: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
146
|
+
socialImage: z.ZodOptional<z.ZodString>;
|
|
147
|
+
prev: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
148
|
+
link: z.ZodOptional<z.ZodString>;
|
|
149
|
+
label: z.ZodOptional<z.ZodString>;
|
|
150
|
+
}, z.core.$strip>, z.ZodLiteral<false>]>>;
|
|
151
|
+
next: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
152
|
+
link: z.ZodOptional<z.ZodString>;
|
|
153
|
+
label: z.ZodOptional<z.ZodString>;
|
|
154
|
+
}, z.core.$strip>, z.ZodLiteral<false>]>>;
|
|
155
|
+
}, z.core.$strip> | z.ZodObject<{
|
|
156
|
+
[x: string]: z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
|
|
157
|
+
}, z.core.$strip>;
|
|
158
|
+
/** Schema for partials (`<Render file="..." />` snippets). */
|
|
159
|
+
declare const partialsSchema: z.ZodDefault<z.ZodObject<{
|
|
160
|
+
params: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
161
|
+
}, z.core.$strip>>;
|
|
162
|
+
//#endregion
|
|
163
|
+
export { DocSchemaConfig, defineDocSchema, docsSchema, partialsSchema };
|
|
164
|
+
//# sourceMappingURL=schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","names":[],"sources":["../src/schemas.ts"],"mappings":";;;UAgBiB,eAAA;;EAEf,MAAA,GAAS,MAAA,SAAe,CAAA,CAAE,UAAA;AAAA;;;;;;iBAgJZ,eAAA,CAAgB,MAAA,GAAQ,eAAA,GAAoB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAS/C,UAAA,EAAU,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAGV,cAAA,EAAc,CAAA,CAAA,UAAA,CAAA,CAAA,CAAA,SAAA"}
|