@eqtylab/docs 0.3.0
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/README.md +201 -0
- package/dist/chunk-55J6XMHW.js +3 -0
- package/dist/chunk-55J6XMHW.js.map +1 -0
- package/dist/chunk-ATIOPYKE.js +102 -0
- package/dist/chunk-ATIOPYKE.js.map +1 -0
- package/dist/chunk-GSSSQTEV.js +51 -0
- package/dist/chunk-GSSSQTEV.js.map +1 -0
- package/dist/chunk-IWKZQ4CW.js +68 -0
- package/dist/chunk-IWKZQ4CW.js.map +1 -0
- package/dist/chunk-K7PJRTK3.js +113 -0
- package/dist/chunk-K7PJRTK3.js.map +1 -0
- package/dist/chunk-VJN3HXKM.js +59 -0
- package/dist/chunk-VJN3HXKM.js.map +1 -0
- package/dist/chunk-ZZ45WAVR.js +20 -0
- package/dist/chunk-ZZ45WAVR.js.map +1 -0
- package/dist/config.d.ts +78 -0
- package/dist/config.js +3 -0
- package/dist/config.js.map +1 -0
- package/dist/dev.d.ts +6 -0
- package/dist/dev.js +84 -0
- package/dist/dev.js.map +1 -0
- package/dist/env.d.ts +17 -0
- package/dist/env.js +3 -0
- package/dist/env.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +421 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/assert-mdx-only.d.ts +1 -0
- package/dist/internal/microlighter-grammars.d.ts +3 -0
- package/dist/internal/pagefind.d.ts +2 -0
- package/dist/internal/rehype-base-url.d.ts +5 -0
- package/dist/internal/rehype-base-url.js +3 -0
- package/dist/internal/rehype-base-url.js.map +1 -0
- package/dist/internal/rehype-code-fence.d.ts +1 -0
- package/dist/internal/rehype-prose-scope.d.ts +1 -0
- package/dist/internal/rehype-table-columns.d.ts +1 -0
- package/dist/internal/scan-consumer-pages.d.ts +7 -0
- package/dist/internal/virtual-config.d.ts +3 -0
- package/dist/loaders.d.ts +20 -0
- package/dist/loaders.js +85 -0
- package/dist/loaders.js.map +1 -0
- package/dist/nav.d.ts +57 -0
- package/dist/nav.js +222 -0
- package/dist/nav.js.map +1 -0
- package/dist/paths.d.ts +28 -0
- package/dist/paths.js +3 -0
- package/dist/paths.js.map +1 -0
- package/dist/runtime/chrome/GlobalSearch.module.css +26 -0
- package/dist/runtime/chrome/GlobalSearch.tsx +422 -0
- package/dist/runtime/chrome/Header.astro +105 -0
- package/dist/runtime/chrome/LinkIcon.astro +35 -0
- package/dist/runtime/chrome/NavDrawer.astro +60 -0
- package/dist/runtime/chrome/NavTree.astro +112 -0
- package/dist/runtime/chrome/NotFoundBody.tsx +12 -0
- package/dist/runtime/chrome/PageFooter.astro +80 -0
- package/dist/runtime/chrome/Prose.astro +169 -0
- package/dist/runtime/chrome/Sidebar.astro +21 -0
- package/dist/runtime/chrome/TableOfContents.astro +86 -0
- package/dist/runtime/chrome/ThemeToggle.tsx +85 -0
- package/dist/runtime/chrome/TocElbow.astro +30 -0
- package/dist/runtime/chrome/TocList.astro +43 -0
- package/dist/runtime/components/AlertBridge.astro +16 -0
- package/dist/runtime/components/CodeFence.astro +38 -0
- package/dist/runtime/components/CodeFenceBridge.astro +20 -0
- package/dist/runtime/components/Link.astro +21 -0
- package/dist/runtime/components/TableBridge.astro +18 -0
- package/dist/runtime/components/index.ts +2 -0
- package/dist/runtime/layouts/DocsPage.astro +50 -0
- package/dist/runtime/layouts/DocsShell.astro +92 -0
- package/dist/runtime/lib/mdx-components.ts +43 -0
- package/dist/runtime/lib/nav-data.ts +74 -0
- package/dist/runtime/lib/summary.ts +57 -0
- package/dist/runtime/lib/theme.ts +84 -0
- package/dist/runtime/routes/docs-md.ts +33 -0
- package/dist/runtime/routes/docs.astro +92 -0
- package/dist/runtime/routes/llms-txt.ts +38 -0
- package/dist/runtime/routes/not-found.astro +16 -0
- package/dist/runtime/scripts/eq-copy.ts +27 -0
- package/dist/runtime/scripts/eq-highlight.ts +24 -0
- package/dist/runtime/scripts/eq-nav-drawer.ts +31 -0
- package/dist/runtime/scripts/eq-nav-group.ts +52 -0
- package/dist/runtime/scripts/eq-toc.ts +166 -0
- package/dist/runtime/styles/chrome.css +30 -0
- package/dist/runtime/styles/docs.css +21 -0
- package/dist/runtime/styles/prose.css +102 -0
- package/dist/runtime/styles/theme.css +2 -0
- package/dist/runtime/styles/utilities.css +38 -0
- package/dist/schema.d.ts +110 -0
- package/dist/schema.js +3 -0
- package/dist/schema.js.map +1 -0
- package/dist/types.d.ts +60 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +127 -0
package/README.md
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# @eqtylab/docs
|
|
2
|
+
|
|
3
|
+
An Astro documentation framework built on the [Equality](https://equality.eqtylab.io) design system.
|
|
4
|
+
One package to build every EQTY docs site — component library, product docs, and API reference —
|
|
5
|
+
with folder-driven navigation and versioned deploys.
|
|
6
|
+
|
|
7
|
+
## Quick start
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @eqtylab/docs @eqtylab/equality astro react react-dom
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
// astro.config.mjs
|
|
15
|
+
import docs from '@eqtylab/docs';
|
|
16
|
+
import { defineConfig } from 'astro/config';
|
|
17
|
+
|
|
18
|
+
export default defineConfig({
|
|
19
|
+
site: 'https://docs.example.com',
|
|
20
|
+
base: process.env.DOCS_BASE ?? '/',
|
|
21
|
+
integrations: [docs({ title: 'My Docs' })],
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
// src/content.config.ts — required; Astro cannot inject collections
|
|
27
|
+
import { docsCollections } from '@eqtylab/docs/loaders';
|
|
28
|
+
|
|
29
|
+
export const collections = docsCollections();
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Then write MDX under `src/content/docs/`. That's the whole setup: the integration injects the
|
|
33
|
+
page routes, a Markdown twin per page, `/llms.txt`, and a 404. Search is built separately, at the
|
|
34
|
+
end of `astro build`; see [Search needs a build](#search-needs-a-build).
|
|
35
|
+
|
|
36
|
+
Content is **MDX-only**. Component overrides apply exclusively to MDX, so a `.md` page would
|
|
37
|
+
render its tables, code fences and callouts differently from every other page. A `.md` file in
|
|
38
|
+
the content tree fails the build rather than going silently missing — renaming it is usually the
|
|
39
|
+
only change needed, since MDX is a superset of Markdown.
|
|
40
|
+
|
|
41
|
+
## Navigation comes from folders
|
|
42
|
+
|
|
43
|
+
Ordering lives in one optional `_group.yaml` per directory — there is deliberately **no
|
|
44
|
+
`sidebar.order` frontmatter** to hand-maintain.
|
|
45
|
+
|
|
46
|
+
```yaml
|
|
47
|
+
# src/content/docs/getting-started/_group.yaml
|
|
48
|
+
label: Getting Started
|
|
49
|
+
order: [installation, usage, themes] # filesystem names, not titles
|
|
50
|
+
collapsed: false
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
- Children listed in `order` come first, in that order.
|
|
54
|
+
- Everything unlisted appends alphabetically by sidebar label (`sort: filename` or `manual` to change that).
|
|
55
|
+
- `index.mdx` in a folder becomes that folder's own landing page.
|
|
56
|
+
- A typo in `order` produces a build **warning naming the file and the token** rather than silently
|
|
57
|
+
reordering, and the schema is `.strict()` so an unknown key fails the build.
|
|
58
|
+
|
|
59
|
+
## Two conventions worth knowing
|
|
60
|
+
|
|
61
|
+
**No Tailwind utility classes in this package's markup.** All styling goes through `@apply` in a
|
|
62
|
+
co-located `*.module.css` with a `@reference` header, mirroring `packages/ui`. This is not a style
|
|
63
|
+
preference: Tailwind v4's source detection skips `node_modules`, so utilities written literally in
|
|
64
|
+
shipped markup would silently produce nothing in a consumer's build. `@apply` has no such
|
|
65
|
+
dependency. `pnpm run check:no-utilities` enforces it and runs as part of `build`.
|
|
66
|
+
|
|
67
|
+
**Route-level MDX components override page-level ones.** `@astrojs/mdx` builds the map as
|
|
68
|
+
`{ Fragment, ...fileComponents, ...props.components }`, so the route's `<Content components={…} />`
|
|
69
|
+
wins over a page's own `export const components`. The route map is therefore kept to element
|
|
70
|
+
overrides (`a`, `pre`); everything richer is an explicit import from `@eqtylab/docs/components`, so
|
|
71
|
+
per-page overrides stay possible.
|
|
72
|
+
|
|
73
|
+
## Code blocks
|
|
74
|
+
|
|
75
|
+
Fenced code renders through Equality's `CodeBlock`, server-side, so docs match product surfaces with
|
|
76
|
+
**no client React**. The highlighter paints through the CSS Custom Highlight API rather than by
|
|
77
|
+
wrapping tokens in markup, so the server-rendered DOM is the final DOM, the palette resolves through
|
|
78
|
+
the normal cascade, and a static render gets correct light _and_ dark colours for free.
|
|
79
|
+
|
|
80
|
+
Two small scripts do what would otherwise need hydration: `runtime/scripts/eq-copy.ts` for the copy
|
|
81
|
+
button, and `runtime/scripts/eq-highlight.ts` to start the highlight pass. Fence tags are passed
|
|
82
|
+
through as authored — the highlighter owns language resolution, including its alias table (`ts`,
|
|
83
|
+
`jsx`, `sh`, `yml` and the rest), and renders plain rather than guessing at a tag it does not know.
|
|
84
|
+
|
|
85
|
+
Set `code: { highlighter: 'shiki' }` to use Astro's Shiki instead: wider language coverage, line
|
|
86
|
+
highlighting and `meta` support, at the cost of a different look from the product.
|
|
87
|
+
|
|
88
|
+
## Everything renders through Equality
|
|
89
|
+
|
|
90
|
+
The framework contributes layout, navigation and prose typography. Everything that renders
|
|
91
|
+
_content_ is an Equality component, server-rendered with no client React, so docs and
|
|
92
|
+
product surfaces cannot drift:
|
|
93
|
+
|
|
94
|
+
| Authored as | Renders as |
|
|
95
|
+
| --------------- | --------------------------------------------------------------------------------------- |
|
|
96
|
+
| Code fences | `CodeBlock` |
|
|
97
|
+
| Markdown tables | `TableContainer` / `TableHeader` / `TableBody` / `TableRow` / `TableHead` / `TableCell` |
|
|
98
|
+
| `<Alert>` | `Alert`, as an `aside` |
|
|
99
|
+
| Links | base-aware `a` override |
|
|
100
|
+
|
|
101
|
+
**Authors write Equality's own components, with no imports.** The route-level component map
|
|
102
|
+
supplies named components as well as element overrides, so this works in any page with
|
|
103
|
+
nothing at the top of the file — there is no docs-specific component vocabulary to learn:
|
|
104
|
+
|
|
105
|
+
```mdx
|
|
106
|
+
---
|
|
107
|
+
title: My page
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
<Alert variant="warning" title="Heads up">
|
|
111
|
+
Body content, with real block elements.
|
|
112
|
+
</Alert>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
The only thing the framework adds is a default: `as="aside"`. Alert's default `div` carries
|
|
116
|
+
`role="alert"`, an assertive live region — right for a message responding to something the
|
|
117
|
+
user did, wrong for a standing note in a document. Importing `Alert` from
|
|
118
|
+
`@eqtylab/equality` explicitly opts out and gives you the raw component, because a
|
|
119
|
+
file-level import wins over the component map.
|
|
120
|
+
|
|
121
|
+
One detail worth knowing: **tables need a column count.** `TableContainer` is a CSS grid
|
|
122
|
+
whose parts all use `subgrid`, so it needs an explicit track list or the table collapses
|
|
123
|
+
to one column. Markdown has no syntax for that, so `rehypeTableColumns` derives the count
|
|
124
|
+
from the first row at build time.
|
|
125
|
+
|
|
126
|
+
This is also why content is MDX-only — these overrides are the mechanism, and Astro's
|
|
127
|
+
plain-Markdown pipeline has no component substitution at all.
|
|
128
|
+
|
|
129
|
+
## Search needs a build
|
|
130
|
+
|
|
131
|
+
Search is full-text, over the built HTML, via [Pagefind](https://pagefind.app). The integration
|
|
132
|
+
runs it in `astro:build:done` and writes the index to `dist/pagefind/`.
|
|
133
|
+
|
|
134
|
+
**One `astro build` makes search work in `astro dev` too.** Dev serves `dist/pagefind/` off disk,
|
|
135
|
+
so results describe the last build; rebuild while dev runs and the next search picks it up. Until
|
|
136
|
+
that first build the palette says search needs one.
|
|
137
|
+
|
|
138
|
+
What gets indexed is set by the markup, not by config:
|
|
139
|
+
|
|
140
|
+
| Attribute | Where | Effect |
|
|
141
|
+
| ---------------------- | -------------------------------- | ------------------------------------- |
|
|
142
|
+
| `data-pagefind-body` | the `<article>` | Bounds the index to page content |
|
|
143
|
+
| `data-pagefind-ignore` | header, sidebar, TOC, action row | Keeps chrome out of every result |
|
|
144
|
+
| `data-pagefind-meta` | the `<h1>` and the `<article>` | Carries `title` and the `group` label |
|
|
145
|
+
|
|
146
|
+
The `group` value is the section's `label` from `_group.yaml`, so search headings and the sidebar
|
|
147
|
+
cannot drift apart.
|
|
148
|
+
|
|
149
|
+
The control itself is a command palette in the header, opened by click, `⌘K` or `/`. Fill the
|
|
150
|
+
header's `search` slot to replace it, or set `search.provider: 'none'` to drop it entirely.
|
|
151
|
+
|
|
152
|
+
## Versioned deploys
|
|
153
|
+
|
|
154
|
+
`base` must be literal in Astro's config at build time, so it is threaded by environment variable:
|
|
155
|
+
|
|
156
|
+
| Variable | Meaning |
|
|
157
|
+
| ------------------- | -------------------------------------------------------------------------- |
|
|
158
|
+
| `DOCS_BASE` | Astro's `base` — `/`, `/v3.1/`, `/repo/v3.1/` |
|
|
159
|
+
| `DOCS_VERSION_ROOT` | Directory holding all version directories (tracked separately from `base`) |
|
|
160
|
+
| `DOCS_VERSION` | This build's version id, e.g. `3.1` |
|
|
161
|
+
| `DOCS_IS_LATEST` | `true` for the canonical build served at root |
|
|
162
|
+
|
|
163
|
+
Every internal URL flows through `@eqtylab/docs/paths`, and authored markdown links are rewritten by
|
|
164
|
+
a rehype plugin — Astro does not do this itself, so without it every root-relative link in content
|
|
165
|
+
would 404 in a sub-path build.
|
|
166
|
+
|
|
167
|
+
## Development
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
pnpm build # guard + node bundle + runtime copy + declarations
|
|
171
|
+
pnpm test # nav ordering, prev/next, breadcrumbs, TOC
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
`src/*.ts` is bundled for Node (it is loaded when Astro reads your config). `src/runtime/**` ships
|
|
175
|
+
as **source** and is compiled by the consumer's Astro — `.astro` files cannot be bundled. The copy is
|
|
176
|
+
verbatim, which is what keeps dev source-linking byte-equivalent to the published package.
|
|
177
|
+
|
|
178
|
+
### The dev surface
|
|
179
|
+
|
|
180
|
+
`packages/demo` — the Equality docs site — is the first-class consumer, so the framework is
|
|
181
|
+
developed against the same site that ships. Run `pnpm dev` from the repo root: this package's
|
|
182
|
+
`dev` keeps `dist/runtime` in sync while the demo serves on port 4321.
|
|
183
|
+
|
|
184
|
+
The sync is what makes edits to `src/runtime/**` hot-reload. Astro resolves injected route
|
|
185
|
+
entrypoints through the real exports map, so `dist/runtime` — not `src/runtime` — is what Vite
|
|
186
|
+
actually serves. Changes to `src/*.ts` are a different matter: they are bundled by tsup and read
|
|
187
|
+
by Astro at config time, so they need `pnpm build:node` and a dev-server restart.
|
|
188
|
+
|
|
189
|
+
To exercise a versioned sub-path build:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
DOCS_BASE=/v0.0/ pnpm --filter demo build
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Then confirm nothing 404s when `packages/demo/dist` is served at `/v0.0/`.
|
|
196
|
+
|
|
197
|
+
### Fixtures
|
|
198
|
+
|
|
199
|
+
`tests/fixtures/basic` is a separate, deliberately minimal consumer used for assertions — it
|
|
200
|
+
contains a misspelled `_group.yaml` key on purpose, which is why it is kept apart from the demo
|
|
201
|
+
rather than doubling as the dev surface.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-55J6XMHW.js"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { z } from 'astro/zod';
|
|
2
|
+
|
|
3
|
+
// src/config.ts
|
|
4
|
+
var headerLink = z.object({
|
|
5
|
+
label: z.string(),
|
|
6
|
+
href: z.string(),
|
|
7
|
+
/**
|
|
8
|
+
* A Lucide name like `BookOpen`, or a path to an SVG in `public/` like
|
|
9
|
+
* `/github.svg`. An SVG must be white: light mode inverts it.
|
|
10
|
+
*/
|
|
11
|
+
icon: z.string().optional(),
|
|
12
|
+
external: z.boolean().optional()
|
|
13
|
+
});
|
|
14
|
+
var docsConfigSchema = z.object({
|
|
15
|
+
/** Site name, shown in the header and used as the `<title>` suffix. */
|
|
16
|
+
title: z.string(),
|
|
17
|
+
description: z.string().optional(),
|
|
18
|
+
/** Path to a favicon, relative to `public/`. Base is applied automatically. */
|
|
19
|
+
favicon: z.string().default("/favicon.svg"),
|
|
20
|
+
/**
|
|
21
|
+
* The header mark. Without one the header falls back to `title` as text. Either
|
|
22
|
+
* way a constant "Docs" label follows it, and `title` heads the sidebar.
|
|
23
|
+
*/
|
|
24
|
+
logo: z.object({
|
|
25
|
+
src: z.string(),
|
|
26
|
+
/** Name the company: the brand link reads as this plus "Docs". */
|
|
27
|
+
alt: z.string().default("")
|
|
28
|
+
}).optional(),
|
|
29
|
+
/** Content directory, relative to `src/`. */
|
|
30
|
+
contentDir: z.string().default("content/docs"),
|
|
31
|
+
/** Mount docs under a sub-path, e.g. 'docs' for /docs/*. Empty means the site root. */
|
|
32
|
+
pathPrefix: z.string().default(""),
|
|
33
|
+
sidebar: z.object({
|
|
34
|
+
/** Default collapse state for groups with no explicit `collapsed`. */
|
|
35
|
+
collapsed: z.boolean().default(false),
|
|
36
|
+
/** Default append order for children absent from a group's `order`. */
|
|
37
|
+
sort: z.enum(["alpha", "filename", "manual"]).default("alpha"),
|
|
38
|
+
/** Extra top-level nodes, appended after folder-derived ones. */
|
|
39
|
+
extra: z.array(z.any()).default([])
|
|
40
|
+
}).prefault({}),
|
|
41
|
+
header: z.object({
|
|
42
|
+
links: z.array(headerLink).default([]),
|
|
43
|
+
showThemeToggle: z.boolean().default(true)
|
|
44
|
+
}).prefault({}),
|
|
45
|
+
footer: z.object({
|
|
46
|
+
/** Base URL for "Edit this page"; the content path is appended. */
|
|
47
|
+
editUrl: z.string().optional(),
|
|
48
|
+
showPrevNext: z.boolean().default(true),
|
|
49
|
+
text: z.string().optional()
|
|
50
|
+
}).prefault({}),
|
|
51
|
+
tableOfContents: z.union([
|
|
52
|
+
z.object({
|
|
53
|
+
minLevel: z.number().int().min(1).max(6).default(2),
|
|
54
|
+
maxLevel: z.number().int().min(1).max(6).default(3)
|
|
55
|
+
}),
|
|
56
|
+
z.literal(false)
|
|
57
|
+
]).prefault({}),
|
|
58
|
+
code: z.object({
|
|
59
|
+
/** 'codeblock' renders fences through Equality's CodeBlock; 'shiki' uses Astro's Shiki. */
|
|
60
|
+
highlighter: z.enum(["codeblock", "shiki"]).default("codeblock"),
|
|
61
|
+
/** Shiki themes; only consulted when `highlighter` is 'shiki'. */
|
|
62
|
+
themes: z.object({ light: z.string(), dark: z.string() }).default({ light: "github-light", dark: "github-dark" }),
|
|
63
|
+
wrap: z.boolean().default(false),
|
|
64
|
+
langs: z.array(z.string()).default([])
|
|
65
|
+
}).prefault({}),
|
|
66
|
+
search: z.object({
|
|
67
|
+
/** 'pagefind' indexes the built HTML. Dev serves that index, so it needs one build. */
|
|
68
|
+
provider: z.enum(["pagefind", "none"]).default("pagefind")
|
|
69
|
+
}).prefault({}),
|
|
70
|
+
routing: z.object({
|
|
71
|
+
/** Inject the catch-all docs route. Disable to own routing entirely. */
|
|
72
|
+
injectPages: z.boolean().default(true),
|
|
73
|
+
/** Emit a `.md` twin per page plus `/llms.txt`. */
|
|
74
|
+
markdownTwins: z.boolean().default(true),
|
|
75
|
+
notFound: z.boolean().default(true)
|
|
76
|
+
}).prefault({}),
|
|
77
|
+
theme: z.object({
|
|
78
|
+
/** 'global' puts tokens on <html>; 'scoped' wraps in a ThemeProvider. */
|
|
79
|
+
mode: z.enum(["global", "scoped"]).default("global"),
|
|
80
|
+
/** Persist the reader's choice to localStorage. */
|
|
81
|
+
persist: z.boolean().default(true)
|
|
82
|
+
}).prefault({}),
|
|
83
|
+
/** Install @astrojs/mdx, @astrojs/react and Tailwind when absent. */
|
|
84
|
+
autoIntegrations: z.boolean().default(true),
|
|
85
|
+
/** Versioning. Left permissive here; the versioning workstream owns the shape. */
|
|
86
|
+
versions: z.any().optional(),
|
|
87
|
+
/** Generated-section plugins (OpenAPI reference, changelogs, ...). */
|
|
88
|
+
plugins: z.array(z.any()).default([])
|
|
89
|
+
});
|
|
90
|
+
function resolveConfig(user) {
|
|
91
|
+
const result = docsConfigSchema.safeParse(user);
|
|
92
|
+
if (!result.success) {
|
|
93
|
+
const issues = result.error.issues.map((i) => ` - ${i.path.join(".") || "(root)"}: ${i.message}`).join("\n");
|
|
94
|
+
throw new Error(`[@eqtylab/docs] Invalid configuration:
|
|
95
|
+
${issues}`);
|
|
96
|
+
}
|
|
97
|
+
return result.data;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export { docsConfigSchema, resolveConfig };
|
|
101
|
+
//# sourceMappingURL=chunk-ATIOPYKE.js.map
|
|
102
|
+
//# sourceMappingURL=chunk-ATIOPYKE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config.ts"],"names":[],"mappings":"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","file":"chunk-ATIOPYKE.js","sourcesContent":["/** Integration options: the whole consumer-facing configuration surface. */\nimport { z } from 'astro/zod';\n\nconst headerLink = z.object({\n label: z.string(),\n href: z.string(),\n /**\n * A Lucide name like `BookOpen`, or a path to an SVG in `public/` like\n * `/github.svg`. An SVG must be white: light mode inverts it.\n */\n icon: z.string().optional(),\n external: z.boolean().optional(),\n});\n\nexport const docsConfigSchema = z.object({\n /** Site name, shown in the header and used as the `<title>` suffix. */\n title: z.string(),\n description: z.string().optional(),\n /** Path to a favicon, relative to `public/`. Base is applied automatically. */\n favicon: z.string().default('/favicon.svg'),\n\n /**\n * The header mark. Without one the header falls back to `title` as text. Either\n * way a constant \"Docs\" label follows it, and `title` heads the sidebar.\n */\n logo: z\n .object({\n src: z.string(),\n /** Name the company: the brand link reads as this plus \"Docs\". */\n alt: z.string().default(''),\n })\n .optional(),\n\n /** Content directory, relative to `src/`. */\n contentDir: z.string().default('content/docs'),\n\n /** Mount docs under a sub-path, e.g. 'docs' for /docs/*. Empty means the site root. */\n pathPrefix: z.string().default(''),\n\n sidebar: z\n .object({\n /** Default collapse state for groups with no explicit `collapsed`. */\n collapsed: z.boolean().default(false),\n /** Default append order for children absent from a group's `order`. */\n sort: z.enum(['alpha', 'filename', 'manual']).default('alpha'),\n /** Extra top-level nodes, appended after folder-derived ones. */\n extra: z.array(z.any()).default([]),\n })\n .prefault({}),\n\n header: z\n .object({\n links: z.array(headerLink).default([]),\n showThemeToggle: z.boolean().default(true),\n })\n .prefault({}),\n\n footer: z\n .object({\n /** Base URL for \"Edit this page\"; the content path is appended. */\n editUrl: z.string().optional(),\n showPrevNext: z.boolean().default(true),\n text: z.string().optional(),\n })\n .prefault({}),\n\n tableOfContents: z\n .union([\n z.object({\n minLevel: z.number().int().min(1).max(6).default(2),\n maxLevel: z.number().int().min(1).max(6).default(3),\n }),\n z.literal(false),\n ])\n .prefault({}),\n\n code: z\n .object({\n /** 'codeblock' renders fences through Equality's CodeBlock; 'shiki' uses Astro's Shiki. */\n highlighter: z.enum(['codeblock', 'shiki']).default('codeblock'),\n /** Shiki themes; only consulted when `highlighter` is 'shiki'. */\n themes: z\n .object({ light: z.string(), dark: z.string() })\n .default({ light: 'github-light', dark: 'github-dark' }),\n wrap: z.boolean().default(false),\n langs: z.array(z.string()).default([]),\n })\n .prefault({}),\n\n search: z\n .object({\n /** 'pagefind' indexes the built HTML. Dev serves that index, so it needs one build. */\n provider: z.enum(['pagefind', 'none']).default('pagefind'),\n })\n .prefault({}),\n\n routing: z\n .object({\n /** Inject the catch-all docs route. Disable to own routing entirely. */\n injectPages: z.boolean().default(true),\n /** Emit a `.md` twin per page plus `/llms.txt`. */\n markdownTwins: z.boolean().default(true),\n notFound: z.boolean().default(true),\n })\n .prefault({}),\n\n theme: z\n .object({\n /** 'global' puts tokens on <html>; 'scoped' wraps in a ThemeProvider. */\n mode: z.enum(['global', 'scoped']).default('global'),\n /** Persist the reader's choice to localStorage. */\n persist: z.boolean().default(true),\n })\n .prefault({}),\n\n /** Install @astrojs/mdx, @astrojs/react and Tailwind when absent. */\n autoIntegrations: z.boolean().default(true),\n\n /** Versioning. Left permissive here; the versioning workstream owns the shape. */\n versions: z.any().optional(),\n\n /** Generated-section plugins (OpenAPI reference, changelogs, ...). */\n plugins: z.array(z.any()).default([]),\n});\n\nexport type DocsUserConfig = z.input<typeof docsConfigSchema>;\nexport type DocsConfig = z.output<typeof docsConfigSchema>;\n\nexport function resolveConfig(user: DocsUserConfig): DocsConfig {\n const result = docsConfigSchema.safeParse(user);\n if (!result.success) {\n const issues = result.error.issues\n .map((i) => ` - ${i.path.join('.') || '(root)'}: ${i.message}`)\n .join('\\n');\n throw new Error(`[@eqtylab/docs] Invalid configuration:\\n${issues}`);\n }\n return result.data;\n}\n"]}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { visit } from 'unist-util-visit';
|
|
2
|
+
|
|
3
|
+
// src/internal/rehype-base-url.ts
|
|
4
|
+
var URL_ATTRS = ["href", "src", "poster"];
|
|
5
|
+
var SRCSET_ATTRS = ["srcSet", "srcset"];
|
|
6
|
+
function shouldRewrite(value, base) {
|
|
7
|
+
if (!value.startsWith("/")) return false;
|
|
8
|
+
if (value.startsWith("//")) return false;
|
|
9
|
+
if (base !== "/" && (value === base.replace(/\/$/, "") || value.startsWith(base))) return false;
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
function rewrite(value, base) {
|
|
13
|
+
return shouldRewrite(value, base) ? base.replace(/\/$/, "") + value : value;
|
|
14
|
+
}
|
|
15
|
+
function rewriteSrcset(value, base) {
|
|
16
|
+
return value.split(",").map((candidate) => {
|
|
17
|
+
const trimmed = candidate.trim();
|
|
18
|
+
if (!trimmed) return candidate;
|
|
19
|
+
const [url, ...descriptors] = trimmed.split(/\s+/);
|
|
20
|
+
return [rewrite(url, base), ...descriptors].join(" ");
|
|
21
|
+
}).join(", ");
|
|
22
|
+
}
|
|
23
|
+
function rehypeBaseUrl(options) {
|
|
24
|
+
const base = options.base || "/";
|
|
25
|
+
return function transformer(tree) {
|
|
26
|
+
if (base === "/") return;
|
|
27
|
+
visit(tree, "element", (node) => {
|
|
28
|
+
const props = node.properties;
|
|
29
|
+
if (!props) return;
|
|
30
|
+
for (const attr of URL_ATTRS) {
|
|
31
|
+
const value = props[attr];
|
|
32
|
+
if (typeof value === "string") props[attr] = rewrite(value, base);
|
|
33
|
+
}
|
|
34
|
+
for (const attr of SRCSET_ATTRS) {
|
|
35
|
+
const value = props[attr];
|
|
36
|
+
if (typeof value === "string") props[attr] = rewriteSrcset(value, base);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function rewriteHtmlBase(html, base) {
|
|
42
|
+
if (!base || base === "/") return html;
|
|
43
|
+
return html.replace(
|
|
44
|
+
/\b(href|src)=("|')(\/(?!\/)[^"']*)\2/g,
|
|
45
|
+
(_match, attr, quote, url) => `${attr}=${quote}${rewrite(url, base)}${quote}`
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export { rehypeBaseUrl, rewriteHtmlBase };
|
|
50
|
+
//# sourceMappingURL=chunk-GSSSQTEV.js.map
|
|
51
|
+
//# sourceMappingURL=chunk-GSSSQTEV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/internal/rehype-base-url.ts"],"names":[],"mappings":";;;AAQA,IAAM,SAAA,GAAY,CAAC,MAAA,EAAQ,KAAA,EAAO,QAAQ,CAAA;AAC1C,IAAM,YAAA,GAAe,CAAC,QAAA,EAAU,QAAQ,CAAA;AAExC,SAAS,aAAA,CAAc,OAAe,IAAA,EAAuB;AAC3D,EAAA,IAAI,CAAC,KAAA,CAAM,UAAA,CAAW,GAAG,GAAG,OAAO,KAAA;AACnC,EAAA,IAAI,KAAA,CAAM,UAAA,CAAW,IAAI,CAAA,EAAG,OAAO,KAAA;AACnC,EAAA,IAAI,IAAA,KAAS,GAAA,KAAQ,KAAA,KAAU,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA,IAAK,KAAA,CAAM,UAAA,CAAW,IAAI,CAAA,CAAA,EAAI,OAAO,KAAA;AAC1F,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,OAAA,CAAQ,OAAe,IAAA,EAAsB;AACpD,EAAA,OAAO,aAAA,CAAc,OAAO,IAAI,CAAA,GAAI,KAAK,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA,GAAI,KAAA,GAAQ,KAAA;AACxE;AAEA,SAAS,aAAA,CAAc,OAAe,IAAA,EAAsB;AAC1D,EAAA,OAAO,MACJ,KAAA,CAAM,GAAG,CAAA,CACT,GAAA,CAAI,CAAC,SAAA,KAAc;AAClB,IAAA,MAAM,OAAA,GAAU,UAAU,IAAA,EAAK;AAC/B,IAAA,IAAI,CAAC,SAAS,OAAO,SAAA;AACrB,IAAA,MAAM,CAAC,GAAA,EAAK,GAAG,WAAW,CAAA,GAAI,OAAA,CAAQ,MAAM,KAAK,CAAA;AACjD,IAAA,OAAO,CAAC,QAAQ,GAAA,EAAe,IAAI,GAAG,GAAG,WAAW,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAAA,EAChE,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AACd;AAEO,SAAS,cAAc,OAAA,EAA2B;AACvD,EAAA,MAAM,IAAA,GAAO,QAAQ,IAAA,IAAQ,GAAA;AAE7B,EAAA,OAAO,SAAS,YAAY,IAAA,EAAe;AACzC,IAAA,IAAI,SAAS,GAAA,EAAK;AAElB,IAAA,KAAA,CAAM,IAAA,EAAe,SAAA,EAAW,CAAC,IAAA,KAAsB;AACrD,MAAA,MAAM,QAAQ,IAAA,CAAK,UAAA;AACnB,MAAA,IAAI,CAAC,KAAA,EAAO;AAEZ,MAAA,KAAA,MAAW,QAAQ,SAAA,EAAW;AAC5B,QAAA,MAAM,KAAA,GAAQ,MAAM,IAAI,CAAA;AACxB,QAAA,IAAI,OAAO,UAAU,QAAA,EAAU,KAAA,CAAM,IAAI,CAAA,GAAI,OAAA,CAAQ,OAAO,IAAI,CAAA;AAAA,MAClE;AAEA,MAAA,KAAA,MAAW,QAAQ,YAAA,EAAc;AAC/B,QAAA,MAAM,KAAA,GAAQ,MAAM,IAAI,CAAA;AACxB,QAAA,IAAI,OAAO,UAAU,QAAA,EAAU,KAAA,CAAM,IAAI,CAAA,GAAI,aAAA,CAAc,OAAO,IAAI,CAAA;AAAA,MACxE;AAAA,IACF,CAAC,CAAA;AAAA,EACH,CAAA;AACF;AAGO,SAAS,eAAA,CAAgB,MAAc,IAAA,EAAsB;AAClE,EAAA,IAAI,CAAC,IAAA,IAAQ,IAAA,KAAS,GAAA,EAAK,OAAO,IAAA;AAClC,EAAA,OAAO,IAAA,CAAK,OAAA;AAAA,IACV,uCAAA;AAAA,IACA,CAAC,MAAA,EAAQ,IAAA,EAAc,KAAA,EAAe,QACpC,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,KAAK,GAAG,OAAA,CAAQ,GAAA,EAAK,IAAI,CAAC,GAAG,KAAK,CAAA;AAAA,GACjD;AACF","file":"chunk-GSSSQTEV.js","sourcesContent":["/** Prefixes root-relative URLs with Astro's `base`, which Astro does not do for authored markdown links. */\nimport { visit } from 'unist-util-visit';\n\ninterface ElementNode {\n type: string;\n properties?: Record<string, unknown>;\n}\n\nconst URL_ATTRS = ['href', 'src', 'poster'];\nconst SRCSET_ATTRS = ['srcSet', 'srcset'];\n\nfunction shouldRewrite(value: string, base: string): boolean {\n if (!value.startsWith('/')) return false;\n if (value.startsWith('//')) return false; // protocol-relative\n if (base !== '/' && (value === base.replace(/\\/$/, '') || value.startsWith(base))) return false;\n return true;\n}\n\nfunction rewrite(value: string, base: string): string {\n return shouldRewrite(value, base) ? base.replace(/\\/$/, '') + value : value;\n}\n\nfunction rewriteSrcset(value: string, base: string): string {\n return value\n .split(',')\n .map((candidate) => {\n const trimmed = candidate.trim();\n if (!trimmed) return candidate;\n const [url, ...descriptors] = trimmed.split(/\\s+/);\n return [rewrite(url as string, base), ...descriptors].join(' ');\n })\n .join(', ');\n}\n\nexport function rehypeBaseUrl(options: { base: string }) {\n const base = options.base || '/';\n\n return function transformer(tree: unknown) {\n if (base === '/') return;\n\n visit(tree as never, 'element', (node: ElementNode) => {\n const props = node.properties;\n if (!props) return;\n\n for (const attr of URL_ATTRS) {\n const value = props[attr];\n if (typeof value === 'string') props[attr] = rewrite(value, base);\n }\n\n for (const attr of SRCSET_ATTRS) {\n const value = props[attr];\n if (typeof value === 'string') props[attr] = rewriteSrcset(value, base);\n }\n });\n };\n}\n\n/** Same, for authored HTML strings in frontmatter. */\nexport function rewriteHtmlBase(html: string, base: string): string {\n if (!base || base === '/') return html;\n return html.replace(\n /\\b(href|src)=(\"|')(\\/(?!\\/)[^\"']*)\\2/g,\n (_match, attr: string, quote: string, url: string) =>\n `${attr}=${quote}${rewrite(url, base)}${quote}`\n );\n}\n"]}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { z } from 'astro/zod';
|
|
2
|
+
|
|
3
|
+
// src/schema.ts
|
|
4
|
+
var badgeSchema = () => z.object({
|
|
5
|
+
text: z.string(),
|
|
6
|
+
variant: z.enum(["primary", "secondary", "neutral", "success", "warning", "danger"]).default("neutral")
|
|
7
|
+
});
|
|
8
|
+
var deprecatedSchema = () => z.union([
|
|
9
|
+
z.boolean(),
|
|
10
|
+
z.object({
|
|
11
|
+
message: z.string().optional(),
|
|
12
|
+
replacedBy: z.string().optional()
|
|
13
|
+
})
|
|
14
|
+
]);
|
|
15
|
+
var tocSchema = () => z.object({
|
|
16
|
+
minLevel: z.number().int().min(1).max(6).default(2),
|
|
17
|
+
maxLevel: z.number().int().min(1).max(6).default(3)
|
|
18
|
+
});
|
|
19
|
+
function docsSchema() {
|
|
20
|
+
return z.object({
|
|
21
|
+
title: z.string(),
|
|
22
|
+
description: z.string().optional(),
|
|
23
|
+
/** Overrides `title` in the sidebar only. */
|
|
24
|
+
navLabel: z.string().optional(),
|
|
25
|
+
/** Lucide icon name. */
|
|
26
|
+
icon: z.string().optional(),
|
|
27
|
+
badge: badgeSchema().optional(),
|
|
28
|
+
/** Omit from the sidebar. The page still builds and is still reachable. */
|
|
29
|
+
hidden: z.boolean().default(false),
|
|
30
|
+
/** Excluded from builds entirely, but visible in `astro dev`. */
|
|
31
|
+
draft: z.boolean().default(false),
|
|
32
|
+
deprecated: deprecatedSchema().default(false),
|
|
33
|
+
/** 'doc' gets sidebar + TOC; 'splash' is full-bleed with neither. */
|
|
34
|
+
template: z.enum(["doc", "splash"]).default("doc"),
|
|
35
|
+
tableOfContents: z.union([tocSchema(), z.literal(false)]).optional(),
|
|
36
|
+
/** Opt out of the markdown twin and the search index for this page. */
|
|
37
|
+
noIndex: z.boolean().default(false),
|
|
38
|
+
prev: z.union([z.boolean(), z.string()]).optional(),
|
|
39
|
+
next: z.union([z.boolean(), z.string()]).optional()
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
var groupLinkSchema = () => z.object({
|
|
43
|
+
label: z.string(),
|
|
44
|
+
href: z.string(),
|
|
45
|
+
/** Inferred from the href when omitted. */
|
|
46
|
+
external: z.boolean().optional(),
|
|
47
|
+
icon: z.string().optional(),
|
|
48
|
+
badge: badgeSchema().optional(),
|
|
49
|
+
attrs: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])).default({})
|
|
50
|
+
});
|
|
51
|
+
function groupSchema() {
|
|
52
|
+
return z.object({
|
|
53
|
+
label: z.string().optional(),
|
|
54
|
+
icon: z.string().optional(),
|
|
55
|
+
/** Immediate-child filesystem names (not titles), in display order. */
|
|
56
|
+
order: z.array(z.string()).default([]),
|
|
57
|
+
/** Children absent from `order`: alpha by label (default), by filename, or manual (dropped from the sidebar). */
|
|
58
|
+
sort: z.enum(["alpha", "filename", "manual"]).optional(),
|
|
59
|
+
collapsed: z.boolean().optional(),
|
|
60
|
+
hidden: z.boolean().default(false),
|
|
61
|
+
badge: badgeSchema().optional(),
|
|
62
|
+
links: z.array(groupLinkSchema()).default([])
|
|
63
|
+
}).strict();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { badgeSchema, docsSchema, groupLinkSchema, groupSchema };
|
|
67
|
+
//# sourceMappingURL=chunk-IWKZQ4CW.js.map
|
|
68
|
+
//# sourceMappingURL=chunk-IWKZQ4CW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schema.ts"],"names":[],"mappings":"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","file":"chunk-IWKZQ4CW.js","sourcesContent":["/** `z` must come from `astro/zod`: a different zod instance breaks Astro's collection validation. */\nimport { z } from 'astro/zod';\n\nexport const badgeSchema = () =>\n z.object({\n text: z.string(),\n variant: z\n .enum(['primary', 'secondary', 'neutral', 'success', 'warning', 'danger'])\n .default('neutral'),\n });\n\nconst deprecatedSchema = () =>\n z.union([\n z.boolean(),\n z.object({\n message: z.string().optional(),\n replacedBy: z.string().optional(),\n }),\n ]);\n\nconst tocSchema = () =>\n z.object({\n minLevel: z.number().int().min(1).max(6).default(2),\n maxLevel: z.number().int().min(1).max(6).default(3),\n });\n\n/** Page frontmatter. Ordering lives in `_group.yaml`, not here. */\nexport function docsSchema() {\n return z.object({\n title: z.string(),\n description: z.string().optional(),\n /** Overrides `title` in the sidebar only. */\n navLabel: z.string().optional(),\n /** Lucide icon name. */\n icon: z.string().optional(),\n badge: badgeSchema().optional(),\n /** Omit from the sidebar. The page still builds and is still reachable. */\n hidden: z.boolean().default(false),\n /** Excluded from builds entirely, but visible in `astro dev`. */\n draft: z.boolean().default(false),\n deprecated: deprecatedSchema().default(false),\n /** 'doc' gets sidebar + TOC; 'splash' is full-bleed with neither. */\n template: z.enum(['doc', 'splash']).default('doc'),\n tableOfContents: z.union([tocSchema(), z.literal(false)]).optional(),\n /** Opt out of the markdown twin and the search index for this page. */\n noIndex: z.boolean().default(false),\n prev: z.union([z.boolean(), z.string()]).optional(),\n next: z.union([z.boolean(), z.string()]).optional(),\n });\n}\n\nexport const groupLinkSchema = () =>\n z.object({\n label: z.string(),\n href: z.string(),\n /** Inferred from the href when omitted. */\n external: z.boolean().optional(),\n icon: z.string().optional(),\n badge: badgeSchema().optional(),\n attrs: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])).default({}),\n });\n\n/** `_group.yaml`. `.strict()` is load-bearing: a typo in an ordering file must fail, not be ignored. */\nexport function groupSchema() {\n return z\n .object({\n label: z.string().optional(),\n icon: z.string().optional(),\n /** Immediate-child filesystem names (not titles), in display order. */\n order: z.array(z.string()).default([]),\n /** Children absent from `order`: alpha by label (default), by filename, or manual (dropped from the sidebar). */\n sort: z.enum(['alpha', 'filename', 'manual']).optional(),\n collapsed: z.boolean().optional(),\n hidden: z.boolean().default(false),\n badge: badgeSchema().optional(),\n links: z.array(groupLinkSchema()).default([]),\n })\n .strict();\n}\n\nexport type DocsFrontmatter = z.infer<ReturnType<typeof docsSchema>>;\nexport type GroupFrontmatter = z.infer<ReturnType<typeof groupSchema>>;\n"]}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { z } from 'astro/zod';
|
|
2
|
+
|
|
3
|
+
// src/config.ts
|
|
4
|
+
var headerLink = z.object({
|
|
5
|
+
label: z.string(),
|
|
6
|
+
href: z.string(),
|
|
7
|
+
/**
|
|
8
|
+
* A Lucide name like `BookOpen`, or a path to an SVG in `public/` like
|
|
9
|
+
* `/github.svg`. An SVG must be white: light mode inverts it.
|
|
10
|
+
*/
|
|
11
|
+
icon: z.string().optional(),
|
|
12
|
+
external: z.boolean().optional()
|
|
13
|
+
});
|
|
14
|
+
var docsConfigSchema = z.object({
|
|
15
|
+
/** Site name, shown in the header and used as the `<title>` suffix. */
|
|
16
|
+
title: z.string(),
|
|
17
|
+
description: z.string().optional(),
|
|
18
|
+
/** Path to a favicon, relative to `public/`. Base is applied automatically. */
|
|
19
|
+
favicon: z.string().default("/favicon.svg"),
|
|
20
|
+
/**
|
|
21
|
+
* The header mark. Without one the header falls back to `title` as text. Either
|
|
22
|
+
* way a constant "Docs" label follows it, and `title` heads the sidebar.
|
|
23
|
+
*/
|
|
24
|
+
logo: z.object({
|
|
25
|
+
src: z.string(),
|
|
26
|
+
/** Name the company: the brand link reads as this plus "Docs". */
|
|
27
|
+
alt: z.string().default("")
|
|
28
|
+
}).optional(),
|
|
29
|
+
/** Content directory, relative to `src/`. */
|
|
30
|
+
contentDir: z.string().default("content/docs"),
|
|
31
|
+
/** Mount docs under a sub-path, e.g. 'docs' for /docs/*. Empty means the site root. */
|
|
32
|
+
pathPrefix: z.string().default(""),
|
|
33
|
+
sidebar: z.object({
|
|
34
|
+
/** Default collapse state for groups with no explicit `collapsed`. */
|
|
35
|
+
collapsed: z.boolean().default(false),
|
|
36
|
+
/** Default append order for children absent from a group's `order`. */
|
|
37
|
+
sort: z.enum(["alpha", "filename", "manual"]).default("alpha"),
|
|
38
|
+
/** Extra top-level nodes, appended after folder-derived ones. */
|
|
39
|
+
extra: z.array(z.any()).default([])
|
|
40
|
+
}).prefault({}),
|
|
41
|
+
header: z.object({
|
|
42
|
+
links: z.array(headerLink).default([]),
|
|
43
|
+
showThemeToggle: z.boolean().default(true)
|
|
44
|
+
}).prefault({}),
|
|
45
|
+
footer: z.object({
|
|
46
|
+
/** Base URL for "Edit this page"; the content path is appended. */
|
|
47
|
+
editUrl: z.string().optional(),
|
|
48
|
+
showPrevNext: z.boolean().default(true),
|
|
49
|
+
text: z.string().optional()
|
|
50
|
+
}).prefault({}),
|
|
51
|
+
tableOfContents: z.union([
|
|
52
|
+
z.object({
|
|
53
|
+
minLevel: z.number().int().min(1).max(6).default(2),
|
|
54
|
+
maxLevel: z.number().int().min(1).max(6).default(3)
|
|
55
|
+
}),
|
|
56
|
+
z.literal(false)
|
|
57
|
+
]).prefault({}),
|
|
58
|
+
code: z.object({
|
|
59
|
+
/** 'codeblock' renders fences through Equality's CodeBlock; 'shiki' uses Astro's Shiki. */
|
|
60
|
+
highlighter: z.enum(["codeblock", "shiki"]).default("codeblock"),
|
|
61
|
+
/** Shiki themes; only consulted when `highlighter` is 'shiki'. */
|
|
62
|
+
themes: z.object({ light: z.string(), dark: z.string() }).default({ light: "github-light", dark: "github-dark" }),
|
|
63
|
+
wrap: z.boolean().default(false),
|
|
64
|
+
langs: z.array(z.string()).default([])
|
|
65
|
+
}).prefault({}),
|
|
66
|
+
search: z.object({
|
|
67
|
+
/** 'pagefind' indexes the built HTML. Dev serves that index, so it needs one build. */
|
|
68
|
+
provider: z.enum(["pagefind", "none"]).default("pagefind")
|
|
69
|
+
}).prefault({}),
|
|
70
|
+
routing: z.object({
|
|
71
|
+
/** Inject the catch-all docs route. Disable to own routing entirely. */
|
|
72
|
+
injectPages: z.boolean().default(true),
|
|
73
|
+
/** Emit a `.md` twin per page plus `/llms.txt`. */
|
|
74
|
+
markdownTwins: z.boolean().default(true),
|
|
75
|
+
notFound: z.boolean().default(true)
|
|
76
|
+
}).prefault({}),
|
|
77
|
+
theme: z.object({
|
|
78
|
+
/** 'global' puts tokens on <html>; 'scoped' wraps in a ThemeProvider. */
|
|
79
|
+
mode: z.enum(["global", "scoped"]).default("global"),
|
|
80
|
+
/** Persist the reader's choice to localStorage. */
|
|
81
|
+
persist: z.boolean().default(true)
|
|
82
|
+
}).prefault({}),
|
|
83
|
+
/**
|
|
84
|
+
* Stylesheets loaded on every docs page. A project-relative path ('./src/styles/site.css')
|
|
85
|
+
* or a package specifier. Resolved against the project root, so dev and build agree.
|
|
86
|
+
*/
|
|
87
|
+
customCss: z.array(z.string()).default([]),
|
|
88
|
+
/**
|
|
89
|
+
* Client modules loaded on every docs page. Bundled rather than served as-is, so they may
|
|
90
|
+
* import from node_modules - which is what a script mutating rendered text needs, since it
|
|
91
|
+
* has to call Equality's `scheduleHighlight` afterwards to repaint code blocks.
|
|
92
|
+
*/
|
|
93
|
+
clientScripts: z.array(z.string()).default([]),
|
|
94
|
+
/** Install @astrojs/mdx, @astrojs/react and Tailwind when absent. */
|
|
95
|
+
autoIntegrations: z.boolean().default(true),
|
|
96
|
+
/** Versioning. Left permissive here; the versioning workstream owns the shape. */
|
|
97
|
+
versions: z.any().optional(),
|
|
98
|
+
/** Generated-section plugins (OpenAPI reference, changelogs, ...). */
|
|
99
|
+
plugins: z.array(z.any()).default([])
|
|
100
|
+
});
|
|
101
|
+
function resolveConfig(user) {
|
|
102
|
+
const result = docsConfigSchema.safeParse(user);
|
|
103
|
+
if (!result.success) {
|
|
104
|
+
const issues = result.error.issues.map((i) => ` - ${i.path.join(".") || "(root)"}: ${i.message}`).join("\n");
|
|
105
|
+
throw new Error(`[@eqtylab/docs] Invalid configuration:
|
|
106
|
+
${issues}`);
|
|
107
|
+
}
|
|
108
|
+
return result.data;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export { docsConfigSchema, resolveConfig };
|
|
112
|
+
//# sourceMappingURL=chunk-K7PJRTK3.js.map
|
|
113
|
+
//# sourceMappingURL=chunk-K7PJRTK3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config.ts"],"names":[],"mappings":"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","file":"chunk-K7PJRTK3.js","sourcesContent":["/** Integration options: the whole consumer-facing configuration surface. */\nimport { z } from 'astro/zod';\n\nconst headerLink = z.object({\n label: z.string(),\n href: z.string(),\n /**\n * A Lucide name like `BookOpen`, or a path to an SVG in `public/` like\n * `/github.svg`. An SVG must be white: light mode inverts it.\n */\n icon: z.string().optional(),\n external: z.boolean().optional(),\n});\n\nexport const docsConfigSchema = z.object({\n /** Site name, shown in the header and used as the `<title>` suffix. */\n title: z.string(),\n description: z.string().optional(),\n /** Path to a favicon, relative to `public/`. Base is applied automatically. */\n favicon: z.string().default('/favicon.svg'),\n\n /**\n * The header mark. Without one the header falls back to `title` as text. Either\n * way a constant \"Docs\" label follows it, and `title` heads the sidebar.\n */\n logo: z\n .object({\n src: z.string(),\n /** Name the company: the brand link reads as this plus \"Docs\". */\n alt: z.string().default(''),\n })\n .optional(),\n\n /** Content directory, relative to `src/`. */\n contentDir: z.string().default('content/docs'),\n\n /** Mount docs under a sub-path, e.g. 'docs' for /docs/*. Empty means the site root. */\n pathPrefix: z.string().default(''),\n\n sidebar: z\n .object({\n /** Default collapse state for groups with no explicit `collapsed`. */\n collapsed: z.boolean().default(false),\n /** Default append order for children absent from a group's `order`. */\n sort: z.enum(['alpha', 'filename', 'manual']).default('alpha'),\n /** Extra top-level nodes, appended after folder-derived ones. */\n extra: z.array(z.any()).default([]),\n })\n .prefault({}),\n\n header: z\n .object({\n links: z.array(headerLink).default([]),\n showThemeToggle: z.boolean().default(true),\n })\n .prefault({}),\n\n footer: z\n .object({\n /** Base URL for \"Edit this page\"; the content path is appended. */\n editUrl: z.string().optional(),\n showPrevNext: z.boolean().default(true),\n text: z.string().optional(),\n })\n .prefault({}),\n\n tableOfContents: z\n .union([\n z.object({\n minLevel: z.number().int().min(1).max(6).default(2),\n maxLevel: z.number().int().min(1).max(6).default(3),\n }),\n z.literal(false),\n ])\n .prefault({}),\n\n code: z\n .object({\n /** 'codeblock' renders fences through Equality's CodeBlock; 'shiki' uses Astro's Shiki. */\n highlighter: z.enum(['codeblock', 'shiki']).default('codeblock'),\n /** Shiki themes; only consulted when `highlighter` is 'shiki'. */\n themes: z\n .object({ light: z.string(), dark: z.string() })\n .default({ light: 'github-light', dark: 'github-dark' }),\n wrap: z.boolean().default(false),\n langs: z.array(z.string()).default([]),\n })\n .prefault({}),\n\n search: z\n .object({\n /** 'pagefind' indexes the built HTML. Dev serves that index, so it needs one build. */\n provider: z.enum(['pagefind', 'none']).default('pagefind'),\n })\n .prefault({}),\n\n routing: z\n .object({\n /** Inject the catch-all docs route. Disable to own routing entirely. */\n injectPages: z.boolean().default(true),\n /** Emit a `.md` twin per page plus `/llms.txt`. */\n markdownTwins: z.boolean().default(true),\n notFound: z.boolean().default(true),\n })\n .prefault({}),\n\n theme: z\n .object({\n /** 'global' puts tokens on <html>; 'scoped' wraps in a ThemeProvider. */\n mode: z.enum(['global', 'scoped']).default('global'),\n /** Persist the reader's choice to localStorage. */\n persist: z.boolean().default(true),\n })\n .prefault({}),\n\n /**\n * Stylesheets loaded on every docs page. A project-relative path ('./src/styles/site.css')\n * or a package specifier. Resolved against the project root, so dev and build agree.\n */\n customCss: z.array(z.string()).default([]),\n\n /**\n * Client modules loaded on every docs page. Bundled rather than served as-is, so they may\n * import from node_modules - which is what a script mutating rendered text needs, since it\n * has to call Equality's `scheduleHighlight` afterwards to repaint code blocks.\n */\n clientScripts: z.array(z.string()).default([]),\n\n /** Install @astrojs/mdx, @astrojs/react and Tailwind when absent. */\n autoIntegrations: z.boolean().default(true),\n\n /** Versioning. Left permissive here; the versioning workstream owns the shape. */\n versions: z.any().optional(),\n\n /** Generated-section plugins (OpenAPI reference, changelogs, ...). */\n plugins: z.array(z.any()).default([]),\n});\n\nexport type DocsUserConfig = z.input<typeof docsConfigSchema>;\nexport type DocsConfig = z.output<typeof docsConfigSchema>;\n\nexport function resolveConfig(user: DocsUserConfig): DocsConfig {\n const result = docsConfigSchema.safeParse(user);\n if (!result.success) {\n const issues = result.error.issues\n .map((i) => ` - ${i.path.join('.') || '(root)'}: ${i.message}`)\n .join('\\n');\n throw new Error(`[@eqtylab/docs] Invalid configuration:\\n${issues}`);\n }\n return result.data;\n}\n"]}
|