@eqtylab/docs 0.3.5 → 0.5.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.
Files changed (54) hide show
  1. package/README.md +77 -12
  2. package/dist/{chunk-VJN3HXKM.js → chunk-LNQV7TVH.js} +18 -6
  3. package/dist/chunk-LNQV7TVH.js.map +1 -0
  4. package/dist/chunk-OM7745ZQ.js +77 -0
  5. package/dist/chunk-OM7745ZQ.js.map +1 -0
  6. package/dist/{chunk-IWKZQ4CW.js → chunk-VNQZJMDO.js} +4 -2
  7. package/dist/chunk-VNQZJMDO.js.map +1 -0
  8. package/dist/{chunk-K7PJRTK3.js → chunk-X4LT7ASQ.js} +31 -4
  9. package/dist/chunk-X4LT7ASQ.js.map +1 -0
  10. package/dist/config.d.ts +10 -1
  11. package/dist/config.js +1 -1
  12. package/dist/index.js +366 -29
  13. package/dist/index.js.map +1 -1
  14. package/dist/internal/extract-versions.d.ts +33 -0
  15. package/dist/internal/rehype-base-url.d.ts +9 -2
  16. package/dist/internal/rehype-base-url.js +1 -1
  17. package/dist/internal/remark-archive-document.d.ts +6 -0
  18. package/dist/internal/run-plugins.d.ts +22 -0
  19. package/dist/internal/virtual-config.d.ts +2 -0
  20. package/dist/loaders.d.ts +5 -5
  21. package/dist/loaders.js +18 -7
  22. package/dist/loaders.js.map +1 -1
  23. package/dist/nav.d.ts +4 -0
  24. package/dist/nav.js +21 -7
  25. package/dist/nav.js.map +1 -1
  26. package/dist/paths.d.ts +25 -3
  27. package/dist/paths.js +1 -1
  28. package/dist/runtime/chrome/GlobalSearch.tsx +7 -2
  29. package/dist/runtime/chrome/Header.astro +8 -3
  30. package/dist/runtime/chrome/NavDrawer.astro +44 -1
  31. package/dist/runtime/chrome/NavTree.astro +1 -11
  32. package/dist/runtime/chrome/Prose.astro +17 -3
  33. package/dist/runtime/chrome/VersionBanner.astro +19 -0
  34. package/dist/runtime/chrome/VersionSwitcher.tsx +105 -0
  35. package/dist/runtime/layouts/DocsPage.astro +36 -4
  36. package/dist/runtime/layouts/DocsShell.astro +4 -2
  37. package/dist/runtime/layouts/RedirectPage.astro +19 -0
  38. package/dist/runtime/lib/mdx-components.ts +4 -1
  39. package/dist/runtime/lib/nav-data.ts +44 -15
  40. package/dist/runtime/lib/versions-ui.ts +12 -0
  41. package/dist/runtime/routes/docs-md.ts +50 -11
  42. package/dist/runtime/routes/docs.astro +182 -73
  43. package/dist/runtime/routes/llms-txt.ts +2 -1
  44. package/dist/runtime/routes/not-found.astro +27 -0
  45. package/dist/schema.d.ts +1 -0
  46. package/dist/schema.js +1 -1
  47. package/dist/types.d.ts +14 -5
  48. package/dist/versions.d.ts +37 -0
  49. package/package.json +16 -16
  50. package/dist/chunk-GSSSQTEV.js +0 -51
  51. package/dist/chunk-GSSSQTEV.js.map +0 -1
  52. package/dist/chunk-IWKZQ4CW.js.map +0 -1
  53. package/dist/chunk-K7PJRTK3.js.map +0 -1
  54. package/dist/chunk-VJN3HXKM.js.map +0 -1
package/README.md CHANGED
@@ -52,7 +52,13 @@ collapsed: false
52
52
 
53
53
  - Children listed in `order` come first, in that order.
54
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.
55
+ - A section's overview always leads it, whether that is the folder's `index.mdx`, a page named
56
+ `overview`, or one titled "Overview" - alphabetical order would otherwise bury it mid-list.
57
+ - `index.mdx` in a folder becomes that folder's own page, listed first in the group as
58
+ **Overview**. A section header only expands - it is never a link - because not every
59
+ section has an index, and a header that navigates only sometimes teaches the wrong habit.
60
+ Rename that row with `indexLabel` on the group, or globally with `sidebar.indexLabel`.
61
+ The content root's `index.mdx` is the site landing page and stays out of the sidebar.
56
62
  - A typo in `order` produces a build **warning naming the file and the token** rather than silently
57
63
  reordering, and the schema is `.strict()` so an unknown key fails the build.
58
64
 
@@ -213,6 +219,38 @@ wired in: `docsEntries` and `pathContext` alongside `docsNav` in `nav-data.ts`,
213
219
  `prevNextFor` / `buildTocTree` re-exported from there, and `mdxComponents` in `mdx-components.ts`
214
220
  for rendering a collection entry through the same component map.
215
221
 
222
+ ## Plugins
223
+
224
+ A plugin is code that runs while Astro reads your config, so it can generate a whole section of
225
+ the site: an API reference from an OpenAPI document, a changelog from git, anything that is
226
+ pages plus a place in the sidebar. Pass instances to `docs({ plugins })`:
227
+
228
+ ```js
229
+ docs({
230
+ title: 'My Docs',
231
+ plugins: [openApiReference({ spec: './public/openapi.yaml' })],
232
+ });
233
+ ```
234
+
235
+ A plugin is `{ name, setup(ctx) }`. `setup` runs inside `astro:config:setup`, after the framework
236
+ has planned its own routes, and receives:
237
+
238
+ - `ctx.astro` — the raw hook params: `config`, `injectRoute`, `updateConfig`, `addWatchFile`,
239
+ `logger`. Inject a route per generated page; its entrypoint can import
240
+ `@eqtylab/docs/layouts/DocsPage.astro`, `@eqtylab/docs/chrome/Prose.astro` and the helpers in
241
+ `@eqtylab/docs/lib/*`, so a generated page gets the same chrome as an authored one.
242
+ - `ctx.addNavGroup(group)` — a `NavNode` appended to the top of the sidebar, after the
243
+ folder-derived groups and `sidebar.extra`. It is static: for current-page state, or to nest
244
+ the group inside an authored section, build the tree in your route instead and pass it to
245
+ `DocsPage`.
246
+ - `ctx.addMdxComponents({ Name: specifier })` — components every MDX page can use without an
247
+ import, by module specifier (a package export or an absolute path) whose default export is the
248
+ component. The runtime imports them through a virtual module, which is why a component object
249
+ cannot be passed. A plugin's entry replaces a default of the same name.
250
+
251
+ A malformed entry, or a component passed as an object, fails the build with a message naming
252
+ the plugin rather than registering nothing.
253
+
216
254
  ## Building the Search Index
217
255
 
218
256
  Full-text search uses the built HTML, via [Pagefind](https://pagefind.app). The integration
@@ -236,20 +274,47 @@ cannot drift apart.
236
274
  The control itself is a command palette in the header, opened by click, `⌘K` or `/`. Fill the
237
275
  header's `search` slot to replace it, or set `search.provider: 'none'` to drop it entirely.
238
276
 
239
- ## Versioned deploys
277
+ ## Versions
240
278
 
241
- `base` must be literal in Astro's config at build time, so it is threaded by environment variable:
279
+ On by default. With release tags in the repository (`v1.2.3`, one per release), the build makes
280
+ one frozen copy of the docs per older group and serves it under `/v<group>/`, adds a switcher to
281
+ the header, a banner and `noindex` to every old page, and scopes search to the page's version.
282
+ Every release tag that is not a copy of its own redirects to its group's copy. Without tags it
283
+ is dormant and the build is unchanged.
242
284
 
243
- | Variable | Meaning |
244
- | ------------------- | -------------------------------------------------------------------------- |
245
- | `DOCS_BASE` | Astro's `base` — `/`, `/v3.1/`, `/repo/v3.1/` |
246
- | `DOCS_VERSION_ROOT` | Directory holding all version directories (tracked separately from `base`) |
247
- | `DOCS_VERSION` | This build's version id, e.g. `3.1` |
248
- | `DOCS_IS_LATEST` | `true` for the canonical build served at root |
285
+ ```js
286
+ docs({
287
+ versions: {
288
+ current: '4.0.0', // defaults to the highest matching tag
289
+ tags: 'v*', // git tag glob; tags not ending in MAJOR.MINOR.PATCH are skipped
290
+ granularity: 'minor', // 'major' (default) | 'minor' | 'patch'
291
+ },
292
+ });
293
+ // or
294
+ docs({ versions: false });
295
+ ```
249
296
 
250
- Every internal URL flows through `@eqtylab/docs/paths`, and authored markdown links are rewritten by
251
- a rehype plugin — Astro does not do this itself, so without it every root-relative link in content
252
- would 404 in a sub-path build.
297
+ What to know:
298
+
299
+ - `current` is never read from your `package.json`. Set it from the product you document, or
300
+ leave it to the highest tag.
301
+ - A tag counts when it **ends** in `MAJOR.MINOR.PATCH`. Any prefix is allowed, so `v1.2.3`,
302
+ `1.2.3`, `sdk-v1.2.3` and `@scope/pkg@1.2.3` all work. Prereleases and anything else are
303
+ skipped with a warning naming the tag.
304
+ - CI needs the tags: check out with `fetch-depth: 0`.
305
+ - If a tag lands one deploy after its bump and `current` is inferred, the `/` label is one
306
+ release behind for that deploy. The content is current; the label heals on the next tag.
307
+ - An archived page is a document, not an app. Prose, headings, tables and code samples are
308
+ kept; live component examples are not rendered, because an old page's imports bind it to
309
+ today's library. The banner says so.
310
+ - Old versions are read-only. A wrong page is fixed by a new tag.
311
+ - Moving `granularity` between `minor` and `patch` does not break published URLs: every grouping
312
+ coarser than the one you set also resolves, so `/v3/` and `/v3.9/` both work at either setting.
313
+ Moving **to `major` does** break them. Only groupings at or coarser than the setting are emitted,
314
+ so at `major` nothing emits `v3.9` and every published `/v3.9/` URL retires.
315
+
316
+ The `DOCS_BASE` family of environment variables still exists for consumers who deploy each
317
+ version as a separate build under its own `base`; this feature does not use them.
253
318
 
254
319
  ## Development
255
320
 
@@ -13,7 +13,7 @@ function ensureTrailingSlash(href) {
13
13
  if (isUnrewritable(href)) return href;
14
14
  const [path, rest = ""] = href.split(/(?=[?#])/, 2);
15
15
  if (path.endsWith("/")) return href;
16
- if (/\.[a-z0-9]+$/i.test(path)) return href;
16
+ if (/\.[a-z0-9]*[a-z][a-z0-9]*$/i.test(path)) return href;
17
17
  return path + "/" + rest;
18
18
  }
19
19
  function idToPath(id) {
@@ -32,11 +32,11 @@ function withBase(path, ctx) {
32
32
  return joinPath(ctx.base, path);
33
33
  }
34
34
  function docsHref(id, ctx) {
35
- return ensureTrailingSlash(joinPath(ctx.base, ctx.versionPrefix, ctx.pathPrefix, idToPath(id)));
35
+ return ensureTrailingSlash(joinPath(ctx.base, ctx.pathPrefix, ctx.versionPrefix, idToPath(id)));
36
36
  }
37
37
  function stripBase(pathname, ctx) {
38
38
  let rest = normalizePath(pathname);
39
- for (const prefix of [ctx.base, ctx.versionPrefix, ctx.pathPrefix]) {
39
+ for (const prefix of [ctx.base, ctx.pathPrefix, ctx.versionPrefix]) {
40
40
  if (!prefix) continue;
41
41
  const norm = normalizePath(joinPath(prefix));
42
42
  if (norm === "/") continue;
@@ -53,7 +53,19 @@ function isAncestor(currentPathname, target) {
53
53
  const t = normalizePath(target);
54
54
  return t === "/" ? current === "/" : current === t || current.startsWith(t + "/");
55
55
  }
56
+ function resolveVersionedPath(pathname, opts) {
57
+ const rest = stripBase(pathname, { base: opts.base, pathPrefix: opts.pathPrefix });
58
+ const segments = rest.replace(/^\/+|\/+$/g, "").split("/");
59
+ const first = segments[0];
60
+ if (!first || !/^v\d/.test(first)) return null;
61
+ const tail = segments.slice(1).join("/");
62
+ const reapply = (version, page) => ensureTrailingSlash(joinPath(opts.base, opts.pathPrefix, version, page));
63
+ if (opts.copyIds.includes(first)) return reapply(first, "");
64
+ const redirect = opts.redirects.find((r) => r.id === first);
65
+ if (!redirect) return null;
66
+ return reapply(redirect.to ?? "", tail);
67
+ }
56
68
 
57
- export { docsHref, ensureTrailingSlash, idToPath, isActive, isAncestor, isExternalHref, joinPath, normalizePath, stripBase, withBase };
58
- //# sourceMappingURL=chunk-VJN3HXKM.js.map
59
- //# sourceMappingURL=chunk-VJN3HXKM.js.map
69
+ export { docsHref, ensureTrailingSlash, idToPath, isActive, isAncestor, isExternalHref, joinPath, normalizePath, resolveVersionedPath, stripBase, withBase };
70
+ //# sourceMappingURL=chunk-LNQV7TVH.js.map
71
+ //# sourceMappingURL=chunk-LNQV7TVH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/paths.ts"],"names":[],"mappings":";AAGO,SAAS,YAAY,KAAA,EAAiD;AAC3E,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAmB,OAAO,CAAA,KAAM,QAAA,IAAY,CAAA,CAAE,MAAA,GAAS,CAAC,CAAA,CAAE,KAAK,GAAG,CAAA;AAC/F,EAAA,OAAO,GAAA,GAAM,OAAO,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA,CAAE,OAAA,CAAQ,WAAW,GAAG,CAAA;AAChE;AAGO,SAAS,eAAe,IAAA,EAAuB;AACpD,EAAA,OAAO,uBAAuB,IAAA,CAAK,IAAI,CAAA,IAAK,IAAA,CAAK,WAAW,IAAI,CAAA;AAClE;AAEA,SAAS,eAAe,IAAA,EAAuB;AAC7C,EAAA,OAAO,cAAA,CAAe,IAAI,CAAA,IAAK,IAAA,CAAK,WAAW,GAAG,CAAA,IAAK,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA;AAC5E;AAEO,SAAS,oBAAoB,IAAA,EAAsB;AACxD,EAAA,IAAI,cAAA,CAAe,IAAI,CAAA,EAAG,OAAO,IAAA;AACjC,EAAA,MAAM,CAAC,MAAM,IAAA,GAAO,EAAE,IAAI,IAAA,CAAK,KAAA,CAAM,YAAY,CAAC,CAAA;AAClD,EAAA,IAAI,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,EAAG,OAAO,IAAA;AAI/B,EAAA,IAAI,6BAAA,CAA8B,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AACrD,EAAA,OAAO,OAAO,GAAA,GAAM,IAAA;AACtB;AAGO,SAAS,SAAS,EAAA,EAAoB;AAC3C,EAAA,OAAO,EAAA,KAAO,UAAU,EAAA,GAAK,EAAA;AAC/B;AAGO,SAAS,cAAc,IAAA,EAAsB;AAClD,EAAA,IAAI,OAAA,GAAU,IAAA;AACd,EAAA,IAAI;AACF,IAAA,OAAA,GAAU,UAAU,IAAI,CAAA;AAAA,EAC1B,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,OAAO,OAAA,CAAQ,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA,IAAK,GAAA;AACxC;AAYO,SAAS,QAAA,CAAS,MAAc,GAAA,EAA0B;AAC/D,EAAA,IAAI,cAAA,CAAe,IAAI,CAAA,EAAG,OAAO,IAAA;AACjC,EAAA,OAAO,QAAA,CAAS,GAAA,CAAI,IAAA,EAAM,IAAI,CAAA;AAChC;AAGO,SAAS,QAAA,CAAS,IAAY,GAAA,EAA0B;AAC7D,EAAA,OAAO,mBAAA,CAAoB,QAAA,CAAS,GAAA,CAAI,IAAA,EAAM,GAAA,CAAI,UAAA,EAAY,GAAA,CAAI,aAAA,EAAe,QAAA,CAAS,EAAE,CAAC,CAAC,CAAA;AAChG;AAGO,SAAS,SAAA,CAAU,UAAkB,GAAA,EAA0B;AACpE,EAAA,IAAI,IAAA,GAAO,cAAc,QAAQ,CAAA;AACjC,EAAA,KAAA,MAAW,MAAA,IAAU,CAAC,GAAA,CAAI,IAAA,EAAM,IAAI,UAAA,EAAY,GAAA,CAAI,aAAa,CAAA,EAAG;AAClE,IAAA,IAAI,CAAC,MAAA,EAAQ;AACb,IAAA,MAAM,IAAA,GAAO,aAAA,CAAc,QAAA,CAAS,MAAM,CAAC,CAAA;AAC3C,IAAA,IAAI,SAAS,GAAA,EAAK;AAClB,IAAA,IAAI,IAAA,KAAS,MAAM,OAAO,GAAA;AAC1B,IAAA,IAAI,IAAA,CAAK,WAAW,IAAA,GAAO,GAAG,GAAG,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,MAAM,CAAA;AAAA,EAChE;AACA,EAAA,OAAO,IAAA,IAAQ,GAAA;AACjB;AAGO,SAAS,QAAA,CAAS,iBAAyB,MAAA,EAAyB;AACzE,EAAA,OAAO,aAAA,CAAc,eAAe,CAAA,KAAM,aAAA,CAAc,MAAM,CAAA;AAChE;AAGO,SAAS,UAAA,CAAW,iBAAyB,MAAA,EAAyB;AAC3E,EAAA,MAAM,OAAA,GAAU,cAAc,eAAe,CAAA;AAC7C,EAAA,MAAM,CAAA,GAAI,cAAc,MAAM,CAAA;AAC9B,EAAA,OAAO,CAAA,KAAM,MAAM,OAAA,KAAY,GAAA,GAAM,YAAY,CAAA,IAAK,OAAA,CAAQ,UAAA,CAAW,CAAA,GAAI,GAAG,CAAA;AAClF;AAoBO,SAAS,oBAAA,CAAqB,UAAkB,IAAA,EAAsC;AAC3F,EAAA,MAAM,IAAA,GAAO,SAAA,CAAU,QAAA,EAAU,EAAE,IAAA,EAAM,KAAK,IAAA,EAAM,UAAA,EAAY,IAAA,CAAK,UAAA,EAAY,CAAA;AACjF,EAAA,MAAM,WAAW,IAAA,CAAK,OAAA,CAAQ,cAAc,EAAE,CAAA,CAAE,MAAM,GAAG,CAAA;AACzD,EAAA,MAAM,KAAA,GAAQ,SAAS,CAAC,CAAA;AACxB,EAAA,IAAI,CAAC,KAAA,IAAS,CAAC,OAAO,IAAA,CAAK,KAAK,GAAG,OAAO,IAAA;AAE1C,EAAA,MAAM,OAAO,QAAA,CAAS,KAAA,CAAM,CAAC,CAAA,CAAE,KAAK,GAAG,CAAA;AACvC,EAAA,MAAM,OAAA,GAAU,CAAC,OAAA,EAAiB,IAAA,KAChC,mBAAA,CAAoB,QAAA,CAAS,IAAA,CAAK,IAAA,EAAM,IAAA,CAAK,UAAA,EAAY,OAAA,EAAS,IAAI,CAAC,CAAA;AAIzE,EAAA,IAAI,IAAA,CAAK,QAAQ,QAAA,CAAS,KAAK,GAAG,OAAO,OAAA,CAAQ,OAAO,EAAE,CAAA;AAE1D,EAAA,MAAM,QAAA,GAAW,KAAK,SAAA,CAAU,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,KAAK,CAAA;AAC1D,EAAA,IAAI,CAAC,UAAU,OAAO,IAAA;AACtB,EAAA,OAAO,OAAA,CAAQ,QAAA,CAAS,EAAA,IAAM,EAAA,EAAI,IAAI,CAAA;AACxC","file":"chunk-LNQV7TVH.js","sourcesContent":["/** Every URL the framework emits goes through here; nothing else may concatenate a path. */\n\n/** Join path segments, collapsing duplicate slashes, always leading with one. */\nexport function joinPath(...parts: Array<string | undefined | null>): string {\n const joined = parts.filter((p): p is string => typeof p === 'string' && p.length > 0).join('/');\n return '/' + joined.replace(/^\\/+/, '').replace(/\\/{2,}/g, '/');\n}\n\n/** True for anything we must not rewrite: protocol, protocol-relative, fragment, or query. */\nexport function isExternalHref(href: string): boolean {\n return /^[a-z][a-z0-9+.-]*:/i.test(href) || href.startsWith('//');\n}\n\nfunction isUnrewritable(href: string): boolean {\n return isExternalHref(href) || href.startsWith('#') || href.startsWith('?');\n}\n\nexport function ensureTrailingSlash(href: string): string {\n if (isUnrewritable(href)) return href;\n const [path, rest = ''] = href.split(/(?=[?#])/, 2);\n if (path.endsWith('/')) return href;\n // Never slash something that looks like a file (/llms.txt, /a.md). The extension must carry a\n // letter: a version id ends `.9`, and treating `/v3.9` as a file drops the slash from every\n // version root, costing a host redirect and breaking exact-match comparisons against it.\n if (/\\.[a-z0-9]*[a-z][a-z0-9]*$/i.test(path)) return href;\n return path + '/' + rest;\n}\n\n/** Astro gives the root `index.mdx` the id \"index\", not \"\". */\nexport function idToPath(id: string): string {\n return id === 'index' ? '' : id;\n}\n\n/** Trim trailing slashes for comparison. Keeps a bare \"/\" intact. */\nexport function normalizePath(path: string): string {\n let decoded = path;\n try {\n decoded = decodeURI(path);\n } catch {\n // Malformed percent-encoding: compare the raw value.\n }\n return decoded.replace(/\\/+$/, '') || '/';\n}\n\nexport interface PathContext {\n /** Astro's `import.meta.env.BASE_URL`. Always has a leading slash. */\n base: string;\n /** Mounted-at prefix for docs pages, e.g. \"docs\". Usually empty. */\n pathPrefix?: string;\n /** Version segment for an older copy, e.g. \"v3.9\". Empty for latest. */\n versionPrefix?: string;\n}\n\n/** Prefix a site-absolute path with `base`. For assets: favicons, logos, og images. */\nexport function withBase(path: string, ctx: PathContext): string {\n if (isUnrewritable(path)) return path;\n return joinPath(ctx.base, path);\n}\n\n/** The public URL for a docs collection entry id. The version rides in the route's slug, so it follows the prefix. */\nexport function docsHref(id: string, ctx: PathContext): string {\n return ensureTrailingSlash(joinPath(ctx.base, ctx.pathPrefix, ctx.versionPrefix, idToPath(id)));\n}\n\n/** Remove `base` (and path/version prefixes) from a pathname, yielding a docs-relative path. */\nexport function stripBase(pathname: string, ctx: PathContext): string {\n let rest = normalizePath(pathname);\n for (const prefix of [ctx.base, ctx.pathPrefix, ctx.versionPrefix]) {\n if (!prefix) continue;\n const norm = normalizePath(joinPath(prefix));\n if (norm === '/') continue;\n if (rest === norm) return '/';\n if (rest.startsWith(norm + '/')) rest = rest.slice(norm.length);\n }\n return rest || '/';\n}\n\n/** Whether `target` is the page currently being viewed. Base-aware, slash-insensitive. */\nexport function isActive(currentPathname: string, target: string): boolean {\n return normalizePath(currentPathname) === normalizePath(target);\n}\n\n/** Whether `target` is the current page or an ancestor of it. Drives group expansion. */\nexport function isAncestor(currentPathname: string, target: string): boolean {\n const current = normalizePath(currentPathname);\n const t = normalizePath(target);\n return t === '/' ? current === '/' : current === t || current.startsWith(t + '/');\n}\n\ninterface VersionFallback {\n base: string;\n pathPrefix?: string;\n /** Ids of versions that have a real copy built. */\n copyIds: string[];\n redirects: Array<{ id: string; to: string | null }>;\n}\n\n/**\n * Where to send a reader whose URL named a release with no page of its own.\n *\n * Static hosting emits a file per URL, and stubs are emitted for bare release URLs only, so\n * `/v3.2.4/` resolves while `/v3.2.4/components/button/` reaches the not-found page. Per-page\n * stubs would be roughly 3,000 files that grow with every release; this recovers the same\n * destination from one page, and unlike the bare stub it keeps the page the reader asked for.\n *\n * Returns null when the path names no version, which is an ordinary 404.\n */\nexport function resolveVersionedPath(pathname: string, opts: VersionFallback): string | null {\n const rest = stripBase(pathname, { base: opts.base, pathPrefix: opts.pathPrefix });\n const segments = rest.replace(/^\\/+|\\/+$/g, '').split('/');\n const first = segments[0];\n if (!first || !/^v\\d/.test(first)) return null;\n\n const tail = segments.slice(1).join('/');\n const reapply = (version: string, page: string) =>\n ensureTrailingSlash(joinPath(opts.base, opts.pathPrefix, version, page));\n\n // The version exists but this page does not: its root forwards to that version's first page.\n // Sending the reader to latest instead would silently show them a different release.\n if (opts.copyIds.includes(first)) return reapply(first, '');\n\n const redirect = opts.redirects.find((r) => r.id === first);\n if (!redirect) return null;\n return reapply(redirect.to ?? '', tail);\n}\n"]}
@@ -0,0 +1,77 @@
1
+ import path from 'path';
2
+ import { visit } from 'unist-util-visit';
3
+
4
+ // src/internal/rehype-base-url.ts
5
+ var URL_ATTRS = ["href", "src", "poster"];
6
+ var SRCSET_ATTRS = ["srcSet", "srcset"];
7
+ function trimSlashes(s) {
8
+ return s.replace(/^\/+|\/+$/g, "");
9
+ }
10
+ function prefixOf(base, pathPrefix, version) {
11
+ const parts = [base, pathPrefix, version].map((p) => p ? trimSlashes(p) : "").filter(Boolean);
12
+ return parts.length ? "/" + parts.join("/") : "";
13
+ }
14
+ function shouldRewrite(value, prefix) {
15
+ if (!value.startsWith("/")) return false;
16
+ if (value.startsWith("//")) return false;
17
+ if (prefix && (value === prefix || value.startsWith(prefix + "/"))) return false;
18
+ return true;
19
+ }
20
+ function rewrite(value, base, pathPrefix, version) {
21
+ const full = prefixOf(base, pathPrefix, version);
22
+ if (!full || !shouldRewrite(value, full)) return value;
23
+ const pp = pathPrefix ? "/" + trimSlashes(pathPrefix) : "";
24
+ if (pp && (value === pp || value.startsWith(pp + "/"))) {
25
+ const rest = value.slice(pp.length);
26
+ return prefixOf(base, pathPrefix, version) + rest;
27
+ }
28
+ return full + value;
29
+ }
30
+ function rewriteSrcset(value, base, pathPrefix, version) {
31
+ return value.split(",").map((candidate) => {
32
+ const trimmed = candidate.trim();
33
+ if (!trimmed) return candidate;
34
+ const [url, ...descriptors] = trimmed.split(/\s+/);
35
+ return [rewrite(url, base, pathPrefix, version), ...descriptors].join(" ");
36
+ }).join(", ");
37
+ }
38
+ function versionFromPath(filePath, versionsDir) {
39
+ if (!filePath || !versionsDir) return void 0;
40
+ const rel = path.relative(versionsDir, filePath);
41
+ if (rel.startsWith("..") || path.isAbsolute(rel)) return void 0;
42
+ return rel.split(path.sep)[0] || void 0;
43
+ }
44
+ function rehypeBaseUrl(options) {
45
+ const base = options.base || "/";
46
+ return function transformer(tree, file) {
47
+ const version = versionFromPath(file?.path ?? file?.history?.[0], options.versionsDir);
48
+ if (base === "/" && !version) return;
49
+ visit(tree, "element", (node) => {
50
+ const props = node.properties;
51
+ if (!props) return;
52
+ for (const attr of URL_ATTRS) {
53
+ const value = props[attr];
54
+ if (typeof value === "string") {
55
+ props[attr] = rewrite(value, base, options.pathPrefix, version);
56
+ }
57
+ }
58
+ for (const attr of SRCSET_ATTRS) {
59
+ const value = props[attr];
60
+ if (typeof value === "string") {
61
+ props[attr] = rewriteSrcset(value, base, options.pathPrefix, version);
62
+ }
63
+ }
64
+ });
65
+ };
66
+ }
67
+ function rewriteHtmlBase(html, base, pathPrefix, version) {
68
+ if ((!base || base === "/") && !version) return html;
69
+ return html.replace(
70
+ /\b(href|src)=("|')(\/(?!\/)[^"']*)\2/g,
71
+ (_match, attr, quote, url) => `${attr}=${quote}${rewrite(url, base, pathPrefix, version)}${quote}`
72
+ );
73
+ }
74
+
75
+ export { rehypeBaseUrl, rewriteHtmlBase, versionFromPath };
76
+ //# sourceMappingURL=chunk-OM7745ZQ.js.map
77
+ //# sourceMappingURL=chunk-OM7745ZQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/internal/rehype-base-url.ts"],"names":[],"mappings":"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","file":"chunk-OM7745ZQ.js","sourcesContent":["/**\n * Prefixes root-relative URLs with Astro's `base`, which Astro does not do for authored\n * markdown links, and with the page's version segment when the file is an extracted copy.\n */\nimport path from 'node:path';\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 trimSlashes(s: string): string {\n return s.replace(/^\\/+|\\/+$/g, '');\n}\n\n/** `/site/` + `docs` + `v3.9` → `/site/docs/v3.9`. Empty parts vanish. Returns '' when nothing applies. */\nfunction prefixOf(\n base: string,\n pathPrefix: string | undefined,\n version: string | undefined\n): string {\n const parts = [base, pathPrefix, version].map((p) => (p ? trimSlashes(p) : '')).filter(Boolean);\n return parts.length ? '/' + parts.join('/') : '';\n}\n\nfunction shouldRewrite(value: string, prefix: string): boolean {\n if (!value.startsWith('/')) return false;\n if (value.startsWith('//')) return false; // protocol-relative\n if (prefix && (value === prefix || value.startsWith(prefix + '/'))) return false;\n return true;\n}\n\n/**\n * When the URL already carries the path prefix (`/docs/x`), the version goes after it (`/docs/v3.9/x`),\n * matching the injected route `${pathPrefix}/[...slug]`.\n */\nfunction rewrite(\n value: string,\n base: string,\n pathPrefix: string | undefined,\n version: string | undefined\n): string {\n const full = prefixOf(base, pathPrefix, version);\n if (!full || !shouldRewrite(value, full)) return value;\n const pp = pathPrefix ? '/' + trimSlashes(pathPrefix) : '';\n if (pp && (value === pp || value.startsWith(pp + '/'))) {\n const rest = value.slice(pp.length);\n return prefixOf(base, pathPrefix, version) + rest;\n }\n return full + value;\n}\n\nfunction rewriteSrcset(value: string, base: string, pathPrefix?: string, version?: 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, pathPrefix, version), ...descriptors].join(' ');\n })\n .join(', ');\n}\n\n/** The version id when `filePath` sits under `<versionsDir>/<id>/`, else undefined. */\nexport function versionFromPath(\n filePath: string | undefined,\n versionsDir: string | undefined\n): string | undefined {\n if (!filePath || !versionsDir) return undefined;\n const rel = path.relative(versionsDir, filePath);\n if (rel.startsWith('..') || path.isAbsolute(rel)) return undefined;\n return rel.split(path.sep)[0] || undefined;\n}\n\nexport function rehypeBaseUrl(options: {\n base: string;\n pathPrefix?: string;\n versionsDir?: string;\n}) {\n const base = options.base || '/';\n\n return function transformer(tree: unknown, file?: { path?: string; history?: string[] }) {\n const version = versionFromPath(file?.path ?? file?.history?.[0], options.versionsDir);\n if (base === '/' && !version) 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') {\n props[attr] = rewrite(value, base, options.pathPrefix, version);\n }\n }\n\n for (const attr of SRCSET_ATTRS) {\n const value = props[attr];\n if (typeof value === 'string') {\n props[attr] = rewriteSrcset(value, base, options.pathPrefix, version);\n }\n }\n });\n };\n}\n\n/** Same, for authored HTML strings in frontmatter. */\nexport function rewriteHtmlBase(\n html: string,\n base: string,\n pathPrefix?: string,\n version?: string\n): string {\n if ((!base || base === '/') && !version) 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, pathPrefix, version)}${quote}`\n );\n}\n"]}
@@ -54,6 +54,8 @@ function groupSchema() {
54
54
  icon: z.string().optional(),
55
55
  /** Immediate-child filesystem names (not titles), in display order. */
56
56
  order: z.array(z.string()).default([]),
57
+ /** Label for the row linking to this folder's own `index.mdx`. Defaults to `sidebar.indexLabel`. */
58
+ indexLabel: z.string().optional(),
57
59
  /** Children absent from `order`: alpha by label (default), by filename, or manual (dropped from the sidebar). */
58
60
  sort: z.enum(["alpha", "filename", "manual"]).optional(),
59
61
  collapsed: z.boolean().optional(),
@@ -64,5 +66,5 @@ function groupSchema() {
64
66
  }
65
67
 
66
68
  export { badgeSchema, docsSchema, groupLinkSchema, groupSchema };
67
- //# sourceMappingURL=chunk-IWKZQ4CW.js.map
68
- //# sourceMappingURL=chunk-IWKZQ4CW.js.map
69
+ //# sourceMappingURL=chunk-VNQZJMDO.js.map
70
+ //# sourceMappingURL=chunk-VNQZJMDO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/schema.ts"],"names":[],"mappings":";;;AAGO,IAAM,WAAA,GAAc,MACzB,CAAA,CAAE,MAAA,CAAO;AAAA,EACP,IAAA,EAAM,EAAE,MAAA,EAAO;AAAA,EACf,OAAA,EAAS,CAAA,CACN,IAAA,CAAK,CAAC,SAAA,EAAW,WAAA,EAAa,SAAA,EAAW,SAAA,EAAW,SAAA,EAAW,QAAQ,CAAC,CAAA,CACxE,QAAQ,SAAS;AACtB,CAAC;AAEH,IAAM,gBAAA,GAAmB,MACvB,CAAA,CAAE,KAAA,CAAM;AAAA,EACN,EAAE,OAAA,EAAQ;AAAA,EACV,EAAE,MAAA,CAAO;AAAA,IACP,OAAA,EAAS,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,IAC7B,UAAA,EAAY,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AAAS,GACjC;AACH,CAAC,CAAA;AAEH,IAAM,SAAA,GAAY,MAChB,CAAA,CAAE,MAAA,CAAO;AAAA,EACP,QAAA,EAAU,CAAA,CAAE,MAAA,EAAO,CAAE,GAAA,EAAI,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,QAAQ,CAAC,CAAA;AAAA,EAClD,QAAA,EAAU,CAAA,CAAE,MAAA,EAAO,CAAE,GAAA,EAAI,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,QAAQ,CAAC;AACpD,CAAC,CAAA;AAGI,SAAS,UAAA,GAAa;AAC3B,EAAA,OAAO,EAAE,MAAA,CAAO;AAAA,IACd,KAAA,EAAO,EAAE,MAAA,EAAO;AAAA,IAChB,WAAA,EAAa,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA;AAAA,IAEjC,QAAA,EAAU,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA;AAAA,IAE9B,IAAA,EAAM,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,IAC1B,KAAA,EAAO,WAAA,EAAY,CAAE,QAAA,EAAS;AAAA;AAAA,IAE9B,MAAA,EAAQ,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAQ,KAAK,CAAA;AAAA;AAAA,IAEjC,KAAA,EAAO,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAQ,KAAK,CAAA;AAAA,IAChC,UAAA,EAAY,gBAAA,EAAiB,CAAE,OAAA,CAAQ,KAAK,CAAA;AAAA;AAAA,IAE5C,QAAA,EAAU,EAAE,IAAA,CAAK,CAAC,OAAO,QAAQ,CAAC,CAAA,CAAE,OAAA,CAAQ,KAAK,CAAA;AAAA,IACjD,eAAA,EAAiB,CAAA,CAAE,KAAA,CAAM,CAAC,SAAA,EAAU,EAAG,CAAA,CAAE,OAAA,CAAQ,KAAK,CAAC,CAAC,CAAA,CAAE,QAAA,EAAS;AAAA;AAAA,IAEnE,OAAA,EAAS,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAQ,KAAK,CAAA;AAAA,IAClC,IAAA,EAAM,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA,CAAE,OAAA,EAAQ,EAAG,CAAA,CAAE,MAAA,EAAQ,CAAC,CAAA,CAAE,QAAA,EAAS;AAAA,IAClD,IAAA,EAAM,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA,CAAE,OAAA,EAAQ,EAAG,CAAA,CAAE,MAAA,EAAQ,CAAC,CAAA,CAAE,QAAA;AAAS,GACnD,CAAA;AACH;AAEO,IAAM,eAAA,GAAkB,MAC7B,CAAA,CAAE,MAAA,CAAO;AAAA,EACP,KAAA,EAAO,EAAE,MAAA,EAAO;AAAA,EAChB,IAAA,EAAM,EAAE,MAAA,EAAO;AAAA;AAAA,EAEf,QAAA,EAAU,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAA,EAAS;AAAA,EAC/B,IAAA,EAAM,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAC1B,KAAA,EAAO,WAAA,EAAY,CAAE,QAAA,EAAS;AAAA,EAC9B,KAAA,EAAO,EAAE,MAAA,CAAO,CAAA,CAAE,QAAO,EAAG,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA,CAAE,MAAA,IAAU,CAAA,CAAE,MAAA,EAAO,EAAG,CAAA,CAAE,OAAA,EAAS,CAAC,CAAC,CAAA,CAAE,OAAA,CAAQ,EAAE;AACxF,CAAC;AAGI,SAAS,WAAA,GAAc;AAC5B,EAAA,OAAO,EACJ,MAAA,CAAO;AAAA,IACN,KAAA,EAAO,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,IAC3B,IAAA,EAAM,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA;AAAA,IAE1B,KAAA,EAAO,EAAE,KAAA,CAAM,CAAA,CAAE,QAAQ,CAAA,CAAE,OAAA,CAAQ,EAAE,CAAA;AAAA;AAAA,IAErC,UAAA,EAAY,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA;AAAA,IAEhC,IAAA,EAAM,EAAE,IAAA,CAAK,CAAC,SAAS,UAAA,EAAY,QAAQ,CAAC,CAAA,CAAE,QAAA,EAAS;AAAA,IACvD,SAAA,EAAW,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAA,EAAS;AAAA,IAChC,MAAA,EAAQ,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAQ,KAAK,CAAA;AAAA,IACjC,KAAA,EAAO,WAAA,EAAY,CAAE,QAAA,EAAS;AAAA,IAC9B,KAAA,EAAO,EAAE,KAAA,CAAM,eAAA,EAAiB,CAAA,CAAE,OAAA,CAAQ,EAAE;AAAA,GAC7C,EACA,MAAA,EAAO;AACZ","file":"chunk-VNQZJMDO.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 /** Label for the row linking to this folder's own `index.mdx`. Defaults to `sidebar.indexLabel`. */\n indexLabel: z.string().optional(),\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"]}
@@ -35,6 +35,11 @@ var docsConfigSchema = z.object({
35
35
  collapsed: z.boolean().default(false),
36
36
  /** Default append order for children absent from a group's `order`. */
37
37
  sort: z.enum(["alpha", "filename", "manual"]).default("alpha"),
38
+ /**
39
+ * Label for the row that links to a section's own `index.mdx`. A section header is
40
+ * never a link - it only expands - so the index page needs a row of its own.
41
+ */
42
+ indexLabel: z.string().default("Overview"),
38
43
  /** Extra top-level nodes, appended after folder-derived ones. */
39
44
  extra: z.array(z.any()).default([])
40
45
  }).prefault({}),
@@ -93,8 +98,30 @@ var docsConfigSchema = z.object({
93
98
  clientScripts: z.array(z.string()).default([]),
94
99
  /** Install @astrojs/mdx, @astrojs/react and Tailwind when absent. */
95
100
  autoIntegrations: z.boolean().default(true),
96
- /** Versioning. Left permissive here; the versioning workstream owns the shape. */
97
- versions: z.any().optional(),
101
+ /**
102
+ * On by default; `false` turns it off. Must be `.prefault`, never `.default`: Zod 4 short-circuits
103
+ * `.default` without parsing, so a consumer who writes nothing would receive a bare `{}` carrying
104
+ * neither `tags` nor `granularity`, and the build would select nothing with no error.
105
+ */
106
+ versions: z.union(
107
+ [
108
+ z.literal(false),
109
+ z.object({
110
+ /** The documented product's version, e.g. '4.0.0'. Defaults to the highest tag matching `tags`. */
111
+ current: z.string().optional(),
112
+ /** Git tag glob for releases. Tags that are not MAJOR.MINOR.PATCH are skipped with a warning. */
113
+ tags: z.string().default("v*"),
114
+ /** One frozen copy per major, per minor, or per release. Releases without a copy redirect to theirs. */
115
+ granularity: z.enum(["major", "minor", "patch"]).default("major")
116
+ }).prefault({})
117
+ ],
118
+ {
119
+ // A union reports its own failure and drops the inner path, so a typo in `granularity`
120
+ // would surface as "versions: Invalid input". Spelling the contract out here is what keeps
121
+ // a misconfigured docsite failing loudly rather than silently versioning nothing.
122
+ error: "expected false, or an object with optional current, tags and granularity (major | minor | patch)"
123
+ }
124
+ ).prefault({}),
98
125
  /** Generated-section plugins (OpenAPI reference, changelogs, ...). */
99
126
  plugins: z.array(z.any()).default([])
100
127
  });
@@ -109,5 +136,5 @@ ${issues}`);
109
136
  }
110
137
 
111
138
  export { docsConfigSchema, resolveConfig };
112
- //# sourceMappingURL=chunk-K7PJRTK3.js.map
113
- //# sourceMappingURL=chunk-K7PJRTK3.js.map
139
+ //# sourceMappingURL=chunk-X4LT7ASQ.js.map
140
+ //# sourceMappingURL=chunk-X4LT7ASQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config.ts"],"names":[],"mappings":"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","file":"chunk-X4LT7ASQ.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 /**\n * Label for the row that links to a section's own `index.mdx`. A section header is\n * never a link - it only expands - so the index page needs a row of its own.\n */\n indexLabel: z.string().default('Overview'),\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 /**\n * On by default; `false` turns it off. Must be `.prefault`, never `.default`: Zod 4 short-circuits\n * `.default` without parsing, so a consumer who writes nothing would receive a bare `{}` carrying\n * neither `tags` nor `granularity`, and the build would select nothing with no error.\n */\n versions: z\n .union(\n [\n z.literal(false),\n z\n .object({\n /** The documented product's version, e.g. '4.0.0'. Defaults to the highest tag matching `tags`. */\n current: z.string().optional(),\n /** Git tag glob for releases. Tags that are not MAJOR.MINOR.PATCH are skipped with a warning. */\n tags: z.string().default('v*'),\n /** One frozen copy per major, per minor, or per release. Releases without a copy redirect to theirs. */\n granularity: z.enum(['major', 'minor', 'patch']).default('major'),\n })\n .prefault({}),\n ],\n {\n // A union reports its own failure and drops the inner path, so a typo in `granularity`\n // would surface as \"versions: Invalid input\". Spelling the contract out here is what keeps\n // a misconfigured docsite failing loudly rather than silently versioning nothing.\n error:\n 'expected false, or an object with optional current, tags and granularity (major | minor | patch)',\n }\n )\n .prefault({}),\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"]}
package/dist/config.d.ts CHANGED
@@ -17,6 +17,7 @@ export declare const docsConfigSchema: z.ZodObject<{
17
17
  filename: "filename";
18
18
  manual: "manual";
19
19
  }>>;
20
+ indexLabel: z.ZodDefault<z.ZodString>;
20
21
  extra: z.ZodDefault<z.ZodArray<z.ZodAny>>;
21
22
  }, z.core.$strip>>;
22
23
  header: z.ZodPrefault<z.ZodObject<{
@@ -70,7 +71,15 @@ export declare const docsConfigSchema: z.ZodObject<{
70
71
  customCss: z.ZodDefault<z.ZodArray<z.ZodString>>;
71
72
  clientScripts: z.ZodDefault<z.ZodArray<z.ZodString>>;
72
73
  autoIntegrations: z.ZodDefault<z.ZodBoolean>;
73
- versions: z.ZodOptional<z.ZodAny>;
74
+ versions: z.ZodPrefault<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodPrefault<z.ZodObject<{
75
+ current: z.ZodOptional<z.ZodString>;
76
+ tags: z.ZodDefault<z.ZodString>;
77
+ granularity: z.ZodDefault<z.ZodEnum<{
78
+ major: "major";
79
+ minor: "minor";
80
+ patch: "patch";
81
+ }>>;
82
+ }, z.core.$strip>>]>>;
74
83
  plugins: z.ZodDefault<z.ZodArray<z.ZodAny>>;
75
84
  }, z.core.$strip>;
76
85
  export type DocsUserConfig = z.input<typeof docsConfigSchema>;
package/dist/config.js CHANGED
@@ -1,3 +1,3 @@
1
- export { docsConfigSchema, resolveConfig } from './chunk-K7PJRTK3.js';
1
+ export { docsConfigSchema, resolveConfig } from './chunk-X4LT7ASQ.js';
2
2
  //# sourceMappingURL=config.js.map
3
3
  //# sourceMappingURL=config.js.map