# API

> Every export of the five packages, from their JSDoc.

{/* Generated by scripts/api-reference.mjs from the JSDoc of the sources: run npm run api:docs rather than editing this page. */}

The five packages are published together, at the same version. Most
projects only need the `docpensieve` command; the packages below are for
what goes further — a script that builds a site, a theme of your own.

Each entry comes from the JSDoc of the source, which the type checker
verifies: it cannot drift from the code without the build noticing.

To use the tool rather than call it, start at
[Installation](/versions/latest/guide/installation/); the fields of a configuration are
in [Configuration](/versions/latest/reference/configuration/).

## `@docpensieve/shared`

Constants, errors and slugs, shared by every package.

### `DOC_EXTENSIONS`

`DOC_EXTENSIONS`

File extensions recognised as documentation pages.

### `CONFIG_FILENAME`

`CONFIG_FILENAME`

Name of the configuration file `init` writes at the project root.

`.mjs` rather than `.js`: the file is an ES module, and Node reads a `.js`
file as one only when the nearest package.json declares "type": "module".
Elsewhere it warns on every build — or refuses the file outright when that
package.json says "commonjs", as `npm init -y` now writes.

### `CONFIG_FILENAMES`

`CONFIG_FILENAMES`

Names accepted for the configuration file, in the order they are looked for.
The `.js` spelling still works in a project whose package.json declares
"type": "module".

### `THEME_FOLDER`

`THEME_FOLDER`

Folder of the project's own stylesheets, at its root. Every `.css` file in
it is appended to the site's stylesheet, after the theme's.

### `DEFAULT_OUT_DIR`

`DEFAULT_OUT_DIR`

Default output directory of a build.

### `VERSIONS_MANIFEST`

`VERSIONS_MANIFEST`

Version manifest written by every build.

### `INDEX_SLUGS`

`INDEX_SLUGS`

Page slugs treated as the root of their folder (they take the folder's own URL).

### `JSONLD_TYPES`

`JSONLD_TYPES`

JSON-LD types supported by the `jsonld.type` frontmatter field.

### `THEME_FRAMEWORKS`

`THEME_FRAMEWORKS`

CSS frameworks known to the ThemeEngine.

### `DOCUMENTATION_URL`

`DOCUMENTATION_URL`

Public address of the documentation.

Written wherever a reader could be stuck — the foot of the help, the
generated configuration, the end of `init` — so it lives in one place
rather than in each of them.

### `PAGE_LAYOUTS`

`PAGE_LAYOUTS`

Layouts accepted in a page's frontmatter.

`doc` is the documentation layout: menu on the left, table of contents on
the right, content held to reading width. `home` removes all three, which
is what a landing page expects.

### `ADMONITION_TONES`

`ADMONITION_TONES`

Tones an admonition can take: what colours it, nothing more.

Here rather than with the component: the configuration validates the kinds a
project declares, and `core` never imports `components` (ADR-002).

### `DocPensieveError`

`class DocPensieveError`

Expected domain error — the CLI prints it without a stack trace.

### `ConfigError`

`class ConfigError`

Configuration missing, unreadable or invalid.

### `LoaderError`

`class LoaderError`

A source file could not be read or parsed.

### `CompileError`

`class CompileError`

MDX/Markdown compilation failed.

### `StructuredDataError`

`class StructuredDataError`

Invalid `jsonld` frontmatter or inconsistent structured data.

### `ThemeError`

`class ThemeError`

Theme provider missing, invalid, or whose compilation failed.

### `GeneratorError`

`class GeneratorError`

The site could not be generated or written.

### `NotImplementedError`

`class NotImplementedError`

Milestone not implemented yet — points to the roadmap section.

### `slugify`

`slugify(input)`

Turns free text into a URL-safe slug.

Accents are decomposed then dropped (`Crème` → `creme`), which keeps URLs
readable instead of percent-encoded.

| Parameter | Type | |
| --- | --- | --- |
| `input` | `string` |  |

**Returns** `string` — Lowercase slug, dash-separated.

### `filePathToSlug`

`filePathToSlug(relativePath)`

Converts a file path, relative to the version folder, into a page slug.

Ordering prefixes are removed from every segment: they sort the sidebar,
they do not build the URL.

| Parameter | Type | |
| --- | --- | --- |
| `relativePath` | `string` | Path relative to the version folder. |

**Returns** `string` — Slug with no leading or trailing slash.

### `assetPathToSlug`

`assetPathToSlug(relativePath)`

Maps an asset path into URL space.

Folders follow the page rule — ordering prefix removed, segment slugified —
so that `02-guide/diagram.png` lands under `/guide/`, where the pages of the
same folder expect it. Otherwise the sorting prefix, which never shows in a
page URL, would show in the URL of its images.

The file name itself stays untouched: it is the one the author writes in
their Markdown, and rewriting it would break the reference.

| Parameter | Type | |
| --- | --- | --- |
| `relativePath` | `string` | Path relative to the version folder. |

**Returns** `string` — Output path, slash-separated.

### `blankSegments`

`blankSegments(relativePath)`

Segments of a path that leave nothing behind once slugified.

`slugify` only keeps Latin letters and digits: a name made entirely of
ideograms, or of punctuation, vanishes. For a page, that meant taking the
home page's URL; for a folder, disappearing from the address.

| Parameter | Type | |
| --- | --- | --- |
| `relativePath` | `string` | Path relative to the version folder. |

**Returns** `string[]` — The offending segments, extension removed.

### `dirPathToSlug`

`dirPathToSlug(relativePath)`

Maps a **folder** path into URL space.

Sibling of `assetPathToSlug`, but with no file name to spare: every segment
goes through the page rule. Applying `assetPathToSlug` to a folder left its
last segment untouched — `02-guide` stayed `02-guide` — and every relative
target of a page in that folder missed the file actually copied.

| Parameter | Type | |
| --- | --- | --- |
| `relativePath` | `string` | Path relative to the version folder. |

**Returns** `string` — Output path, slash-separated.

### `slugToUrl`

`slugToUrl(slug, [versionSlug])`

Converts a page slug into an absolute site URL (trailing slash included).

| Parameter | Type | |
| --- | --- | --- |
| `slug` | `string` | Slug produced by \{@link filePathToSlug\}. |
| `[versionSlug]` | `string` | When given, prefixes `/versions/<version>`. |

**Returns** `string` — URL starting and ending with `/`.

### `humanizeSlug`

`humanizeSlug(segment)`

Turns a slug segment back into a readable label.

A deliberate, imperfect fallback: since `slugify` dropped the accents,
`creme-brulee` comes back as “Creme brulee”. Only use it when there is no
real title — the sidebar and the breadcrumb prefer the frontmatter title.

| Parameter | Type | |
| --- | --- | --- |
| `segment` | `string` |  |

**Returns** `string`

### `orderOf`

`orderOf(filename)`

Reads the ordering weight of a prefixed file name.

| Parameter | Type | |
| --- | --- | --- |
| `filename` | `string` |  |

**Returns** `number` — The prefix number, or `Infinity` when absent (sorted last).

### `UI_STRINGS`

`UI_STRINGS`

The shipped languages.

### `DEFAULT_LANGUAGE`

`DEFAULT_LANGUAGE`

Language used when nothing else is known.

### `uiStrings`

`uiStrings([lang], [overrides])`

The wording of a language, completed by English for anything it omits.

| Parameter | Type | |
| --- | --- | --- |
| `[lang]` | `string` | Language code, `fr` or `fr-CA`. |
| `[overrides]` | `Record<string, Partial<UiStrings>>` | Wording declared by the project. |

**Returns** `UiStrings`

### `pageCount`

`pageCount(count, strings, [lang])`

Counts pages in the language of the page.

The plural category comes from the language itself, through the CLDR rules
`Intl` carries: `count === 1` is an English rule and gets French wrong on
zero — "0 page", not "0 pages" — and has nothing to say about Polish or
Arabic, which have four and six categories.

| Parameter | Type | |
| --- | --- | --- |
| `count` | `number` |  |
| `strings` | `UiStrings` |  |
| `[lang]` | `string` | Language of the page. |

**Returns** `string` — For instance `12 pages` or `1 page`.

### `textDirection`

`textDirection([lang])`

Writing direction of a language, for the `dir` attribute.

Read from the language rather than from a list of our own: `Intl` carries
what CLDR knows, and a list would go stale the day someone translates into
a language nobody thought of.

| Parameter | Type | |
| --- | --- | --- |
| `[lang]` | `string` |  |

**Returns** `'ltr' \| 'rtl'` — `ltr` when the language is unknown — the safe default, and what every page did before this existed.

## `@docpensieve/core`

Configuration, loading, compilation, structured data and generation.

### `DEFAULT_CONFIG`

`DEFAULT_CONFIG`

Values applied when the user config leaves them out.

The type is spelled out: without it, TypeScript would infer
`versions: never[]` from the empty array and refuse every read of its
elements elsewhere in the file.

### `defineConfig`

`defineConfig(config)`

Identity over the config, used only for autocompletion and type checking
in the editor.

| Parameter | Type | |
| --- | --- | --- |
| `config` | `T` |  |

**Returns** `T`

### `loadConfig`

`loadConfig([cwd])`

Loads the configuration file of a project folder.

`docpensieve.config.mjs` is looked for first, then `docpensieve.config.js`,
which a project whose package.json declares "type": "module" can still use.

| Parameter | Type | |
| --- | --- | --- |
| `[cwd]` | `string` | Project root. Default: `process.cwd()`. |

**Returns** `Promise<DocPensieveConfig>` — Normalised config.

**Throws** `ConfigError` — When no file, or two, are found, or when the file does not load or exports no object.

### `normalizeConfig`

`normalizeConfig(userConfig)`

Merges the user config with the defaults and validates it.

| Parameter | Type | |
| --- | --- | --- |
| `userConfig` | `Record<string, unknown>` |  |

**Returns** `DocPensieveConfig` — Normalised config.

**Throws** `ConfigError` — When the config is structurally invalid.

### `resolveVersion`

`resolveVersion(config, [slug])`

Finds a declared version by its slug.

| Parameter | Type | |
| --- | --- | --- |
| `config` | `DocPensieveConfig` | Normalised config. |
| `[slug]` | `string` | Slug to look for. Omitted: the "current" version. |

**Returns** `Version` — The requested version.

**Throws** `ConfigError` — When the slug does not exist.

### `DocLoader`

`class DocLoader`

Walks a version folder and produces the list of documents.

### `Compiler`

`class Compiler`

Compiles an MDX/Markdown source into an HTML fragment.

### `StructuredDataBuilder`

`class StructuredDataBuilder`

Assembles a schema.org graph for a page.

### `SiteGenerator`

`class SiteGenerator`

Generates the static site of one or more versions.

### `buildSidebar`

`buildSidebar(docs, [toUrl], [options])`

Builds the navigation tree of a version.

The order is the `DocLoader`'s, which has already sorted: index page first,
then numeric prefixes, then alphabetical. Nothing is re-sorted here, which
guarantees that the sidebar follows the reading order of the files exactly.

That order has a useful consequence: since `guide/index.md` is loaded
before `guide/installation.md`, the “guide” category receives its real
title before a child page creates it with a default one.

| Parameter | Type | |
| --- | --- | --- |
| `docs` | `import('./loader.js').Doc[]` | Documents in loader order. |
| `[toUrl]` | `(doc: import('./loader.js').Doc) => string` | Turns a document into a URL. By default, the document's URL as is. |
| `[options]` | `{ brand?: string }` | `brand` is the name shown in the header: a root entry carrying exactly that title is dropped, since the brand already leads to that page. The same word twice, an inch apart, tells the reader nothing. |

**Returns** `SidebarNode[]`

### `buildSidebarFromDescription`

`buildSidebarFromDescription(description, docs, [toUrl], [options])`

Builds the navigation tree of a version from a description.

The description is an array of entries, kept in the order written:

- `"guide/installation"` — a page, by its path within the version, as in
  its URL; `"/"` is the home page. Its title becomes the label.
- `{ "page": "guide/installation", "label": "Install" }` — the same, with a
  label of its own.
- `{ "label": "Guide", "items": [ … ], "page": "guide" }` — a category,
  clickable when it names a page.
- `{ "label": "Repository", "href": "https://…" }` — a link outside the site.
- `{ "auto": "docpensieve" }` — the automatic tree of a folder: a section
  keeps its own menu without listing its pages one by one.

A page left out stays published: it is only absent from the menu, which is
how a page is kept off it.

| Parameter | Type | |
| --- | --- | --- |
| `description` | `unknown` | Parsed content of the description file. |
| `docs` | `import('./loader.js').Doc[]` | Documents of the version. |
| `[toUrl]` | `(doc: import('./loader.js').Doc) => string` | As for `buildSidebar`. |
| `[options]` | `{ source?: string }` | `source` names the file in messages. |

**Returns** `SidebarNode[]`

**Throws** `ConfigError` — For a path that names no page, a page listed twice, or an entry of no known kind.

### `collectSectionTitles`

`collectSectionTitles(docs)`

Collects folder titles, for the breadcrumb.

Only folders with an index page have a known title; the others will be
humanised from their slug by `StructuredDataBuilder`.

| Parameter | Type | |
| --- | --- | --- |
| `docs` | `import('./loader.js').Doc[]` |  |

**Returns** `Record<string, string>` — Full folder slug to title.

### `foldSidebar`

`foldSidebar(nodes, [currentUrl])`

| Parameter | Type | |
| --- | --- | --- |
| `nodes` | `SidebarNode[]` |  |
| `[currentUrl]` | `string` | URL of the page being rendered. |

**Returns** `FoldedNode[]`

### `buildFeed`

`buildFeed(pages, site)`

Builds the RSS feed of the dated pages, newest first.

Only a page with a `date` enters it: a documentation page without one is
reference material, not news, and dating it at build time would announce
every page again at every build.

| Parameter | Type | |
| --- | --- | --- |
| `pages` | `PublishedPage[]` | Pages of the current version. |
| `site` | `{ projectName: string, siteUrl: string, homeUrl: string, feedUrl: string, lang?: string, }` | `homeUrl` and `feedUrl` are absolute. |

**Returns** `string`

### `buildRobots`

`buildRobots(sitemapUrl)`

Builds `robots.txt`, which lets every crawler in and names the sitemap.

| Parameter | Type | |
| --- | --- | --- |
| `sitemapUrl` | `string` | Absolute address of the sitemap. |

**Returns** `string`

### `buildSitemap`

`buildSitemap(pages, siteUrl)`

Builds `sitemap.xml`.

`lastmod` is the page's `modified` date, or failing that its `date`; a page
that carries neither is listed without one rather than with a made-up date.

| Parameter | Type | |
| --- | --- | --- |
| `pages` | `PublishedPage[]` | Pages of the versions to list. |
| `siteUrl` | `string` | Public address of the site: the sitemap only holds absolute addresses. |

**Returns** `string`

### `buildAuthorTable`

`buildAuthorTable(description, options)`

Turns the JSON description of a version into a table of authors.

| Parameter | Type | |
| --- | --- | --- |
| `description` | `unknown` | Parsed content of the file. |
| `options` | `{ source: string }` | `source` names the file in errors. |

**Returns** `Map<string, Author>`

**Throws** `ConfigError` — When the shape is wrong, naming the offending entry.

### `buildByline`

`buildByline(frontmatter, [table], [where], [locale])`

Assembles what the head of a page shows, or nothing when it has none of it.

| Parameter | Type | |
| --- | --- | --- |
| `frontmatter` | `Record<string, any>` |  |
| `[table]` | `Map<string, Author>` |  |
| `[where]` | `string` | Page named in a date error. |
| `[locale]` | `string` | Locale the dates are written in. |

**Returns** `Byline \| null`

**Throws** `ConfigError` — When a date cannot be read.

### `readDate`

`readDate(value, field, where, [locale])`

Reads a date of the frontmatter, and gives it in both forms: the machine one
for `<time datetime>`, the readable one for the reader.

A date is often written unquoted in YAML, which parses it as a Date; quoted,
it arrives as text. Both are accepted, anything unreadable is refused rather
than shown as `Invalid Date`.

| Parameter | Type | |
| --- | --- | --- |
| `value` | `unknown` |  |
| `field` | `string` | Name of the field, for the error message. |
| `where` | `string` | Page the date comes from. |
| `[locale]` | `string` | Locale the label is written in. Default: `en-GB`. |

**Returns** `{ iso: string, label: string } \| null` — `null` when absent.

**Throws** `ConfigError` — When the value is not a date.

### `resolvePageAuthors`

`resolvePageAuthors(value, [table])`

The authors of a page, in the order the frontmatter names them.

A key the table does not describe is not an error: the name is shown as
written. It is what lets a project name its authors before describing them,
and what keeps pages written before the file working.

| Parameter | Type | |
| --- | --- | --- |
| `value` | `unknown` | `authors` from the frontmatter: one name or a list. |
| `[table]` | `Map<string, Author>` |  |

**Returns** `Author[]`

## `@docpensieve/theme`

The theme providers and the engine that composes them.

### `BaseThemeProvider`

`class BaseThemeProvider`

Base class to extend in order to plug in a CSS framework.

A provider generates no HTML: it supplies CSS, variables and a table of
class aliases. That is what lets a single template render correctly under
Tailwind as well as under the custom theme.

### `CustomProvider`

`class CustomProvider`

Custom theme: hand-written CSS, no dependency.

### `DEFAULT_TOKENS`

`DEFAULT_TOKENS`

Palette and measures of the light theme.

Dark mode does not live here: it fits in two blocks of `custom.css`, since
a flat table of variables cannot express a media query.

### `TailwindProvider`

`class TailwindProvider`

Tailwind theme: on-demand compilation of the classes actually used.

### `ThemeEngine`

`class ThemeEngine`

Combines several providers into a single CSS output.

## `@docpensieve/components`

The components available in every page.

### `classNames`

`classNames(parts)`

Joins classes while ignoring falsy values.

A minimal equivalent of `clsx`: one more dependency is not worth it for six
lines.

| Parameter | Type | |
| --- | --- | --- |
| `parts` | `...unknown` |  |

**Returns** `string \| undefined` — `undefined` when nothing is left, to avoid a `class=""` in the produced HTML.

### `cls`

`cls(slot, modifiers)`

Class of a slot, variants included.

| Parameter | Type | |
| --- | --- | --- |
| `slot` | `string` | Slot name. |
| `modifiers` | `...unknown` | Variants, each one suffixed as `--variant`. Falsy values are ignored, which allows writing `cls('card', shadow && shadow)`. |

**Returns** `string`

### `fallbackClass`

`fallbackClass(slot)`

Converts a slot name into a fallback class.

| Parameter | Type | |
| --- | --- | --- |
| `slot` | `string` |  |

**Returns** `string`

### `getThemeClasses`

`getThemeClasses()`

@returns \{Record&lt;string, string>\} The current table, for inspection.

### `getThemeFramework`

`getThemeFramework()`

@returns \{string\} The active framework, or `''` when none was announced.

### `setThemeClasses`

`setThemeClasses([classes])`

Declares the theme table for the whole compilation.

| Parameter | Type | |
| --- | --- | --- |
| `[classes]` | `Record<string, string>` |  |

### `setThemeFramework`

`setThemeFramework([framework])`

Declares the framework of the active theme, which `ForTheme` reads.

| Parameter | Type | |
| --- | --- | --- |
| `[framework]` | `string` |  |

### `ADMONITION_KINDS`

`ADMONITION_KINDS`

The kinds the tool ships with, each a label and a tone.

`alert` and `danger` share a tone and differ in their label and their icon:
one calls for attention now, the other warns of what a wrong move costs.

### `Admonition`

`Admonition(props)`

Block set apart from the text.

| Parameter | Type | |
| --- | --- | --- |
| `props` | `{ className?: string, style?: object, children?: any, type?: string, title?: string, }` | `type` names the kind; `title` replaces its label for this block alone. |

**Throws** `DocPensieveError` — When the kind is unknown.

### `getAdmonitionKinds`

`getAdmonitionKinds()`

@returns \{Record&lt;string, \{ label: string, tone: string, icon?: string \}>\} Every kind available.

### `setAdmonitionKinds`

`setAdmonitionKinds([kinds])`

Declares the kinds of the project, beside the ones shipped.

| Parameter | Type | |
| --- | --- | --- |
| `[kinds]` | `Record<string, { label: string, tone: string, icon?: string }>` |  |

### `Card`

`Card(props)`

Card container.

| Parameter | Type | |
| --- | --- | --- |
| `props` | `PartProps & { elevated?: boolean, href?: string }` | `elevated` adds a shadow. `href` makes the whole card clickable, rather than a link on the title alone that would leave the rest inert. |

### `CardBody`

Documented in `packages/components/src/card.js`.

### `CardFooter`

Documented in `packages/components/src/card.js`.

### `CardHeader`

Documented in `packages/components/src/card.js`.

### `CardImage`

`CardImage(props)`

Image at the top of a card.

`src` resolves as in Markdown — relative to the page, absolute from the
version root. The compiler plugins cannot handle it: they work on the
Markdown tree, before React renders anything. So the component does it
itself (ADR-006).

| Parameter | Type | |
| --- | --- | --- |
| `props` | `{ className?: string, style?: object, src?: string, alt?: string, title?: string, srcSet?: string, sizes?: string, loading?: 'lazy' \| 'eager', }` | `alt` defaults to the empty string: without that attribute, a screen reader would announce the file URL. |

### `Cards`

`Cards(props)`

Grid of cards for the children of a folder.

| Parameter | Type | |
| --- | --- | --- |
| `props` | `{ className?: string, style?: object, of?: 'all' \| 'series' \| 'pages', from?: string, }` | `of` narrows the grid to the sub-folders (`'series'`) or to the pages beside the index (`'pages'`); `from` reads another folder, named by its slug, instead of the one holding the page. |

**Throws** `Error` — When the page list is missing, or `from` names nothing.

### `Column`

`Column(props)`

Column of a row.

| Parameter | Type | |
| --- | --- | --- |
| `props` | `{ className?: string, style?: object, children?: any, span?: number }` | `span` is the number of tracks taken out of twelve — `span={6}` for a half, `span={8}` for two thirds. Twelve because twelve divides by two, three, four and six. Without `span`, the columns share the space equally. |

**Throws** `DocPensieveError` — Outside a `Columns`, or when the row mixes columns with and without a width.

### `Columns`

`Columns(props)`

Row of columns.

The gap is set through `className` or `style`, with the theme's utilities:
the grid recomputes the widths by itself.

| Parameter | Type | |
| --- | --- | --- |
| `props` | `{ className?: string, style?: object, children?: any }` |  |

### `Menu`

`Menu(props)`

Menu of links.

| Parameter | Type | |
| --- | --- | --- |
| `props` | `{ className?: string, style?: object, children?: any, label?: string, }` | `label` names the menu for screen readers, and labels the button it folds into on a narrow screen. |

### `MenuGroup`

`MenuGroup(props)`

Group of entries, folded under a title.

In the row it opens as a panel below its title; folded, it unfolds in place
rather than over the rest — on a narrow screen a panel would open off
screen.

| Parameter | Type | |
| --- | --- | --- |
| `props` | `{ className?: string, style?: object, children?: any, title?: string, }` |  |

**Throws** `DocPensieveError` — Outside a `Menu`, or without a title.

### `MenuLink`

`MenuLink(props)`

Entry of a menu.

| Parameter | Type | |
| --- | --- | --- |
| `props` | `{ className?: string, style?: object, children?: any, href?: string, }` |  |

**Throws** `DocPensieveError` — Outside a `Menu`, or without a target.

### `FallbackAfter`

`FallbackAfter(props)`

Content shown after the period.

Without a wrapper, for the same reason as \{@link FallbackBefore\}.

| Parameter | Type | |
| --- | --- | --- |
| `props` | `{ children?: any, end?: string }` |  |

### `FallbackBefore`

`FallbackBefore(props)`

Content shown before the period.

No wrapper: a `span` around the author's content would become invalid
markup as soon as they write a paragraph in it — which happens as soon as a
blank line separates their text. The content therefore keeps its nature,
inline or block.

| Parameter | Type | |
| --- | --- | --- |
| `props` | `{ children?: any, start?: string }` |  |

### `TimeTimer`

`TimeTimer(props)`

Shows its content during a period, with fallbacks before and after.

| Parameter | Type | |
| --- | --- | --- |
| `props` | `{ date?: string, start?: string, duration?: string, strict?: boolean, children?: any, now?: Date, }` | `now` only exists for tests: without it, the build moment stands. |

### `TOOLTIP_PLACEMENTS`

`TOOLTIP_PLACEMENTS`

Sides the bubble can sit on.

### `Tooltip`

`Tooltip(props)`

Term with a tooltip.

| Parameter | Type | |
| --- | --- | --- |
| `props` | `{ className?: string, style?: object, children?: any, text?: string, placement?: string, }` | `text` is the content of the bubble; the children are the term it explains. |

**Throws** `DocPensieveError` — Without text, or with an unknown side.

### `Tree`

`Tree(props)`

Root of a tree.

| Parameter | Type | |
| --- | --- | --- |
| `props` | `{ className?: string, style?: object, children?: any }` |  |

### `TreeItem`

`TreeItem(props)`

Entry of a tree.

With children, it is a collapsible branch; without, a leaf. The difference
is read from the writing, with no prop to set.

| Parameter | Type | |
| --- | --- | --- |
| `props` | `{ className?: string, style?: object, children?: any, label?: any, open?: boolean, }` | `open` expands the branch as soon as the page opens. |

**Throws** `DocPensieveError` — Outside a `Tree`, or without a label.

### `ScrollToTop`

`ScrollToTop(props)`

Back-to-top button.

| Parameter | Type | |
| --- | --- | --- |
| `props` | `{ className?: string, style?: object, children?: any, label?: string, }` | `label` is read by screen readers. The children replace the arrow with whatever you want. |

### `SKILL_SHAPES`

`SKILL_SHAPES`

Shapes accepted by the gauge.

### `Skill`

`Skill(props)`

Named gauge, from 0 to 100.

| Parameter | Type | |
| --- | --- | --- |
| `props` | `{ className?: string, style?: object, children?: any, name?: any, level?: number, showValue?: boolean, shape?: string, icon?: any, color?: string, label?: string, }` | `children` stands as a comment under the gauge. `showValue` hides the numeric percentage without touching what the gauge announces. `shape` picks between the bar and the circle. `icon` goes before the name — a `LogoIcon` fits there. `color` tints the fill: any CSS colour, the accent colour by default. `label` names the gauge for screen readers when `name` is not text. |

**Throws** `DocPensieveError` — Without a name, outside 0–100, or with an unknown shape.

### `LogoIcon`

`LogoIcon(props)`

Project SVG icon, inlined in the page.

| Parameter | Type | |
| --- | --- | --- |
| `props` | `{ className?: string, style?: object, src?: string, label?: string, size?: string, }` | `label` describes the icon; without it the icon is treated as decorative and hidden from screen readers — which is right when nearby text already says the same thing. `size` accepts any CSS length. |

**Throws** `DocPensieveError` — Without `src`, or when the file cannot be read.

### `ForTheme`

`ForTheme(props)`

Renders its children only when the site's theme is `framework`.

| Parameter | Type | |
| --- | --- | --- |
| `props` | `{ framework?: string, children?: any }` |  |

**Returns** `any`

**Throws** `DocPensieveError` — For a framework the configuration does not know, or when no theme was announced.

### `componentsCss`

`componentsCss()`

Reads the default look of the components.

It is concatenated with the theme's by the caller: a provider that
redefines a slot replaces the `dp-*` class with its own, and these rules
then stop applying by themselves.

**Returns** `Promise<string>` — CSS, trimmed.

**Throws** `DocPensieveError` — When the stylesheet is missing.

### `getSiteContext`

`getSiteContext()`

@returns \{SiteContext\} The current context.

### `resolveFile`

`resolveFile(target)`

Resolves a target into a file path, for a resource read at build time.

Same landmarks as for a URL, mapped to the disk: a relative target starts
from the page's file, an absolute one from the version folder. Nothing can
leave that folder — a page does not read the rest of the machine.

| Parameter | Type | |
| --- | --- | --- |
| `target` | `string` |  |

**Returns** `string` — Absolute path, inside the source folder.

**Throws** `Error` — When the context is missing or the target escapes it.

### `resolveUrl`

`resolveUrl(target)`

Resolves a target written by an author into a site URL.

Same rules as for Markdown content: a relative target resolves against the
page's folder, an absolute target starts from the version root.

| Parameter | Type | |
| --- | --- | --- |
| `target` | `string \| undefined` |  |

**Returns** `string \| undefined` — The resolved target, or as is when external.

### `setSiteContext`

`setSiteContext([page])`

Declares the page being rendered.

Set by the generator before every page, like the class table.

| Parameter | Type | |
| --- | --- | --- |
| `[page]` | `Partial<SiteContext>` |  |

### `builtinComponents`

`builtinComponents`

Components shipped with DocPensieve.

### `createRegistry`

`createRegistry([userComponents])`

Builds the component table passed to the MDX compiler.

| Parameter | Type | |
| --- | --- | --- |
| `[userComponents]` | `Record<string, Function>` | Project components, which override the built-in components of the same name. |

**Returns** `Record<string, Function>` — Table ready for @mdx-js/mdx.

### `listComponentNames`

`listComponentNames(registry)`

Lists the available component names — useful for a readable error message
when an `.mdx` references an unknown component.

| Parameter | Type | |
| --- | --- | --- |
| `registry` | `Record<string, Function>` |  |

**Returns** `string[]` — Names sorted alphabetically.

## `docpensieve`

The commands, callable from a script as well as from the terminal.

### `build`

`build(versionSlug, [options])`

| Parameter | Type | |
| --- | --- | --- |
| `versionSlug` | `string \| undefined` | Version to generate, or all of them when omitted. |
| `[options]` | `{ out?: string, cwd?: string }` |  |

**Returns** `Promise<void>`

### `check`

`check([options])`

Reads the produced site back and reports what is wrong.

| Parameter | Type | |
| --- | --- | --- |
| `[options]` | `{ dir?: string, cwd?: string }` |  |

**Returns** `Promise<{ root: string, pages: number, faults: Fault[] }>`

**Throws** `DocPensieveError` — When the folder does not exist, or when something is left to fix — the exit code is then that of an expected error, which is enough to fail a continuous integration run.

### `verifyLinks`

`verifyLinks(root, [baseUrl])`

Checks the internal links of a generated site.

Exported apart from the command: it reads no configuration and addresses no
one, which makes it usable elsewhere and testable on its own.

| Parameter | Type | |
| --- | --- | --- |
| `root` | `string` | Folder of the produced site. |
| `[baseUrl]` | `string` | Deployment prefix, slashes included. |

**Returns** `Promise<{ pages: number, faults: Fault[] }>`

### `verifyMarkup`

`verifyMarkup(root)`

Checks the markup of a generated site.

| Parameter | Type | |
| --- | --- | --- |
| `root` | `string` | Folder of the produced site. |

**Returns** `Promise<{ pages: number, faults: Fault[] }>`

### `dev`

`dev([options])`

| Parameter | Type | |
| --- | --- | --- |
| `[options]` | `{ port?: number, cwd?: string }` |  |

**Returns** `Promise<{ server: import('node:http').Server, watcher: import('chokidar').FSWatcher, port: number, url: string, close: () => Promise<void>, }>`

### `init`

`init([dir], [options])`

Sets up a documentation project.

| Parameter | Type | |
| --- | --- | --- |
| `[dir]` | `string` | Target folder, created if needed. |
| `[options]` | `{ name?: string, theme?: string, siteUrl?: string, version?: string, yes?: boolean, force?: boolean, minimal?: boolean, }` | `minimal` leaves DocPensieve's documentation out of the site. |

**Returns** `Promise<{ dir: string, theme: string, docs: boolean }>`

**Throws** `DocPensieveError` — Unknown framework, project already initialised, or documentation to install missing.

### `serve`

`serve([options])`

| Parameter | Type | |
| --- | --- | --- |
| `[options]` | `{ port?: number, dir?: string, cwd?: string }` |  |

**Returns** `Promise<{ server: import('node:http').Server, port: number, url: string }>`

**Throws** `DocPensieveError` — When the folder to serve does not exist.

### `createStaticServer`

`createStaticServer(options)`

Creates a static file server.

| Parameter | Type | |
| --- | --- | --- |
| `options` | `{ root: string, basePath?: string, inject?: string \| null, onReload?: (send: () => void) => void, }` | `basePath` is the prefix under which the site is mounted: it must reflect the configuration's `baseUrl`, otherwise the links of the pages do not resolve locally. `inject` is an HTML fragment inserted before `</body>` — the development server uses it for its reload script, which leaves the generated output intact. |

**Returns** `import('node:http').Server`

### `listen`

`listen(server, port, [attempts])`

Starts listening, looking for a free port if needed.

| Parameter | Type | |
| --- | --- | --- |
| `server` | `import('node:http').Server` |  |
| `port` | `number` | Desired port. |
| `[attempts]` | `number` | Number of ports tried from `port` on. |

**Returns** `Promise<number>` — The port actually used.

**Throws** `DocPensieveError` — When no port is free in the range.

### `resolveRequestPath`

`resolveRequestPath(pathname, root)`

Resolves a request URL into a file path, without leaving the root.

| Parameter | Type | |
| --- | --- | --- |
| `pathname` | `string` | Request path, `basePath` already removed. |
| `root` | `string` | Served folder. |

**Returns** `string \| null` — Absolute path, or `null` when the target escapes `root`.
