import { foldAccents, slugifySegment } from '../slug.js'; export { foldAccents, slugifySegment }; import type { DocEntry, NormalizedSection, NoteType, SectionEntry } from '../types.js'; export type TreeNodeType = 'folder' | 'group' | 'component' | 'pattern' | 'doc' | 'page' | 'layout'; export interface TreeNode { name: string; type: TreeNodeType; /** Display path segments from the section root */ path: string[]; /** URL route segments from the site root (slugified, section included) */ route: string[]; /** Children nodes */ children: TreeNode[]; /** The doc entry (only for component/page/layout nodes) */ doc?: DocEntry; /** True on the entity's own node (not its Docs/example children) */ entity?: boolean; /** Set on example child nodes: the example this node opens */ snippetName?: string; /** Example titles for component nodes (sidebar sub-pages) */ examples?: string[]; /** Whether this node should be expanded by default */ defaultExpanded?: boolean; /** The worst note in this row's subtree, itself included — what the * sidebar marks it with. Absent when nothing in it carries a note. */ mark?: NoteMark | null; } /** What a sidebar row says about the notes at and under it. */ export interface NoteMark { /** The worst intent found; `null` is a note written without one. */ type: NoteType | null; /** The worst one is this row's own note, rather than something inside it. */ own: boolean; } /** One top-bar section: a tab label and its own sidebar tree */ export interface SectionTree { slug: string; title: string; tree: TreeNode[]; /** Route of the section's first document (top-bar tab target) */ firstRoute: string[] | null; /** A `{ type: 'divider' }` entry followed this section — the bar draws a * rule after its tab. */ dividerAfter: boolean; } /** What a URL route resolves to */ export interface RouteTarget { doc: DocEntry; snippetName?: string; /** Slug of the section the route lives in; unset for sectionless pages, * which render without a sidebar. */ section?: string; } /** A site-structure problem: shown full-page in dev, fails the build. */ export interface SiteError { message: string; /** Absolute .sdoc path when the error points at one file */ file?: string; } /** Everything the Explorer needs to render sections and resolve URLs */ export interface SectionMap { sections: SectionTree[]; routes: Map; /** True when the config declared sections — routes carry the section slug */ active: boolean; /** What the root route renders (from the config `home` path) */ home: RouteTarget | null; /** Structure problems: unknown sections, route collisions, a bad home path */ errors: SiteError[]; } export declare function normalizeSections(sections: SectionEntry[] | undefined): NormalizedSection[]; /** Split an optional `@section-slug` first segment off a title. */ export declare function splitSection(title: string | null | undefined): { section: string | null; rest: string; }; export interface BuildSectionsOptions { /** Declared sections in top-bar order (raw config shape is accepted) */ sections?: SectionEntry[]; /** Route path of the landing page, e.g. 'guides/introduction' */ home?: string | null; } /** * Group docs into their declared sections, build each section's tree, apply * the per-section `order` arrays, and register every navigable route. * Structure problems — an unknown `@section`, two entities on one route, a * `home` path that resolves nowhere — are collected as errors, not repaired: * the Explorer shows them full-page and `sdocs build` fails on them. */ export declare function buildSections(docs: DocEntry[], opts?: BuildSectionsOptions): SectionMap; /** Resolve URL segments to a doc. */ export declare function resolveRoute(map: SectionMap, segments: string[]): RouteTarget | null; /** Build a tree from flat doc entries; routes get `routePrefix` prepended. */ export declare function buildTree(docs: DocEntry[], routePrefix?: string[], errors?: SiteError[]): TreeNode[]; /** * The title shown to users. The `@section/` prefix routes to a top-bar * section and a leading ':' on the first segment is a sidebar grouping * directive (see buildTree) — neither is part of the displayed title. */ export declare function displayTitle(title: string | null | undefined): string;