@unterberg/nivel 0.0.1 → 0.0.3

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 (55) hide show
  1. package/README.md +115 -0
  2. package/bin/nivel.mjs +3 -0
  3. package/dist/{chunk-73NPVCDQ.js → chunk-D7IAGT53.js} +56 -26
  4. package/dist/chunk-D7IAGT53.js.map +1 -0
  5. package/dist/chunk-DNCQR5NH.js +231 -0
  6. package/dist/chunk-DNCQR5NH.js.map +1 -0
  7. package/dist/{chunk-3JJ6TYWL.js → chunk-FARXFRHG.js} +120 -83
  8. package/dist/chunk-FARXFRHG.js.map +1 -0
  9. package/dist/chunk-K5ZYRA3G.js +198 -0
  10. package/dist/chunk-K5ZYRA3G.js.map +1 -0
  11. package/dist/{chunk-4WTEOEV2.js → chunk-L6ZVB6XH.js} +3 -3
  12. package/dist/chunk-L6ZVB6XH.js.map +1 -0
  13. package/dist/{chunk-FLO5CJZH.js → chunk-PYYPYIBD.js} +10 -3
  14. package/dist/chunk-PYYPYIBD.js.map +1 -0
  15. package/dist/{chunk-45CLUNJW.js → chunk-Q7JU4J6A.js} +69 -33
  16. package/dist/chunk-Q7JU4J6A.js.map +1 -0
  17. package/dist/chunk-UDOIFPCZ.js +1538 -0
  18. package/dist/chunk-UDOIFPCZ.js.map +1 -0
  19. package/dist/cli.d.ts +3 -0
  20. package/dist/cli.js +78 -0
  21. package/dist/cli.js.map +1 -0
  22. package/dist/client.d.ts +4 -8
  23. package/dist/client.js +4 -4
  24. package/dist/index.d.ts +8 -12
  25. package/dist/index.js +4 -8
  26. package/dist/{code-blocks.d.ts → mdx/code-blocks.d.ts} +3 -1
  27. package/dist/{code-blocks.js → mdx/code-blocks.js} +5 -3
  28. package/dist/mdx.js +4 -4
  29. package/dist/mdx.js.map +1 -1
  30. package/dist/runtime/client.d.ts +1 -1
  31. package/dist/runtime/client.js +4 -4
  32. package/dist/runtime/node.d.ts +23 -0
  33. package/dist/runtime/node.js +24 -0
  34. package/dist/{types-mvLNHHrf.d.ts → types-j0kEkMA4.d.ts} +47 -24
  35. package/dist/{config.js → vike.js} +9 -8
  36. package/dist/vike.js.map +1 -0
  37. package/package.json +25 -16
  38. package/tailwind-sources.css +1 -0
  39. package/assets/nivel/decorators/pattern-light.png +0 -0
  40. package/assets/nivel/decorators/pattern.png +0 -0
  41. package/dist/chunk-3JJ6TYWL.js.map +0 -1
  42. package/dist/chunk-45CLUNJW.js.map +0 -1
  43. package/dist/chunk-4WTEOEV2.js.map +0 -1
  44. package/dist/chunk-62MBEYU7.js +0 -1091
  45. package/dist/chunk-62MBEYU7.js.map +0 -1
  46. package/dist/chunk-73NPVCDQ.js.map +0 -1
  47. package/dist/chunk-FLO5CJZH.js.map +0 -1
  48. package/dist/chunk-PHHK2BAF.js +0 -350
  49. package/dist/chunk-PHHK2BAF.js.map +0 -1
  50. package/dist/config.js.map +0 -1
  51. package/dist/runtime/index.d.ts +0 -15
  52. package/dist/runtime/index.js +0 -18
  53. /package/dist/{code-blocks.js.map → mdx/code-blocks.js.map} +0 -0
  54. /package/dist/runtime/{index.js.map → node.js.map} +0 -0
  55. /package/dist/{config.d.ts → vike.d.ts} +0 -0
package/README.md ADDED
@@ -0,0 +1,115 @@
1
+ # nivel engine
2
+
3
+ docs builder proof of concept for generating vike-based documentation sites with a single docs graph as the source of truth.
4
+
5
+ monorepo structure:
6
+
7
+ - `packages/engine`: the reusable `@unterberg/nivel` package
8
+ - `packages/consumer-test`: the reference consumer used to exercise the engine against real docs content, currently based on the [Telefunc docs](https://telefunc.com)
9
+
10
+ ## Alpha Status
11
+
12
+ This project is an early proof of concept and should be expected to have rough edges. The main goal is to validate the core engine ideas and architecture, not to provide a polished general-purpose doc builder right now. Some specific things to keep in mind:
13
+
14
+ - Expect breaking changes.
15
+ - The public API is not stable yet. (blackbox)
16
+ - The supported stack fixed currently to Vike + Vite + React.
17
+ - `basePath` is currently fixed to `/docs`.
18
+ - The consumer app in this repo is still the main integration example.
19
+
20
+ If you need a polished general-purpose docpress replacement today, this is not that yet.
21
+
22
+ ## What It Does
23
+
24
+ The engine currently owns the core docs runtime:
25
+
26
+ - docs graph validation and resolution
27
+ - generated Vike routes from MDX content
28
+ - shared docs layout pieces such as navbar, sidebar, table of contents, pagination, and meta head wiring
29
+ - MDX setup with built-in docs components and code-block transforms
30
+ - asset handling for engine-owned fonts and shared static assets
31
+
32
+ The intended split is:
33
+
34
+ - the engine owns behavior, runtime wiring, and reusable UI primitives
35
+ - the consumer owns docs content, `docs/docs.graph.ts`, `pages/+docs.ts`, and brand/theme assets
36
+
37
+ ## Minimal Shape
38
+
39
+ At the moment, a consumer looks roughly like this:
40
+
41
+ ```ts
42
+ // pages/+docs.ts
43
+ import { defineDocsConfig } from '@unterberg/nivel'
44
+ import { docsGraph } from '../docs/docs.graph'
45
+
46
+ export default defineDocsConfig({
47
+ siteTitle: 'My Docs',
48
+ basePath: '/docs',
49
+ graph: docsGraph,
50
+ algolia: {
51
+ appId: 'YOUR_APP_ID',
52
+ apiKey: 'YOUR_SEARCH_ONLY_API_KEY',
53
+ indexName: 'YOUR_INDEX_NAME',
54
+ },
55
+ })
56
+ ```
57
+
58
+ ```ts
59
+ // docs/docs.graph.ts
60
+ import { defineDocsGraph } from '@unterberg/nivel'
61
+
62
+ export const docsGraph = defineDocsGraph({
63
+ items: [
64
+ {
65
+ kind: 'section',
66
+ id: 'docs',
67
+ title: 'Documentation',
68
+ items: [
69
+ {
70
+ kind: 'page',
71
+ id: 'quickStart',
72
+ title: 'Quick Start',
73
+ slug: 'quick-start',
74
+ source: 'content/quick-start/content.mdx',
75
+ },
76
+ ],
77
+ },
78
+ ],
79
+ })
80
+ ```
81
+
82
+ Then the consumer wires:
83
+
84
+ - `@unterberg/nivel/vike` into Vike config
85
+ - `MetaHead` in global `+Head`
86
+ - `AppLayout` in global `+Layout`
87
+ - `nivel prepare` before dev/build/typecheck
88
+ - `@import '@unterberg/nivel/tailwind-sources.css'` in the consumer Tailwind entry
89
+
90
+ Algolia search is optional. When configured, `apiKey` must be a search-only public key because requests are made from the browser.
91
+
92
+ ## Current Limitations
93
+
94
+ - The package is still alpha and should be expected to change.
95
+ - The supported stack is currently narrow: Vike + Vite + React.
96
+ - `basePath` is currently fixed to `/docs`.
97
+ - The package is still validated mainly through one real consumer, not a broad set of independent adopters.
98
+ - The setup and examples are still catching up with the implementation, so the integration story is not fully polished yet.
99
+
100
+ ## Future Plans
101
+
102
+ - Continue hardening the engine/consumer split so docs behavior stays in `@unterberg/nivel` and the consumer remains thin.
103
+ - Improve the package-level docs and examples so setup is easier to understand without reading the consumer app in detail.
104
+ - Reduce hard-coded assumptions where it makes sense, starting with the areas that currently make the engine feel too tied to its first consumer.
105
+
106
+ ## Commands
107
+
108
+ ```bash
109
+ pnpm install
110
+ pnpm dev
111
+ pnpm build
112
+ pnpm typecheck
113
+ pnpm format
114
+ pnpm knip
115
+ ```
package/bin/nivel.mjs ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ import '../dist/cli.js'
@@ -2,9 +2,9 @@ import {
2
2
  nivelAssetUrl,
3
3
  resolvePublicAssetUrl,
4
4
  withSiteBaseUrl
5
- } from "./chunk-FLO5CJZH.js";
5
+ } from "./chunk-PYYPYIBD.js";
6
6
 
7
- // src/runtime/resolveDocsConfig.ts
7
+ // src/docs/resolveDocsConfig.ts
8
8
  var normalizeBasePath = (value) => {
9
9
  const normalized = value.trim().replace(/^\/+|\/+$/g, "");
10
10
  return `/${normalized}`;
@@ -31,13 +31,19 @@ var normalizeSourcePath = (value) => {
31
31
  }
32
32
  return normalizedSegments.join("/");
33
33
  };
34
- var getSectionHref = (items) => {
34
+ var getSectionHref = (items, visibleOnly = false) => {
35
35
  for (const item of items) {
36
36
  if (item.kind === "page") {
37
+ if (visibleOnly && !item.showInNav) {
38
+ continue;
39
+ }
37
40
  return item.href;
38
41
  }
39
42
  if (item.kind === "group") {
40
- const href = getSectionHref(item.items);
43
+ if (visibleOnly && !item.showInNav) {
44
+ continue;
45
+ }
46
+ const href = getSectionHref(item.items, visibleOnly);
41
47
  if (href) {
42
48
  return href;
43
49
  }
@@ -45,6 +51,13 @@ var getSectionHref = (items) => {
45
51
  }
46
52
  return null;
47
53
  };
54
+ var resolveNavigationHref = (value, fieldName) => {
55
+ const normalized = value.trim();
56
+ if (!normalized) {
57
+ throw new Error(`Docs ${fieldName} must be a non-empty string.`);
58
+ }
59
+ return normalizePathname(normalized);
60
+ };
48
61
  var resolveThemeConfig = (theme) => {
49
62
  return {
50
63
  light: theme?.light ?? "consumer-light",
@@ -105,6 +118,30 @@ var resolvePartnersConfig = (partners) => {
105
118
  gold: (partners?.gold ?? []).map(resolvePartner)
106
119
  };
107
120
  };
121
+ var requireTrimmedString = (value, fieldName) => {
122
+ const normalized = value.trim();
123
+ if (!normalized) {
124
+ throw new Error(`Docs algolia config "${fieldName}" must be a non-empty string.`);
125
+ }
126
+ return normalized;
127
+ };
128
+ var resolveAlgoliaConfig = (algolia) => {
129
+ if (!algolia) {
130
+ return null;
131
+ }
132
+ return {
133
+ appId: requireTrimmedString(algolia.appId, "appId"),
134
+ apiKey: requireTrimmedString(algolia.apiKey, "apiKey"),
135
+ indexName: requireTrimmedString(algolia.indexName, "indexName"),
136
+ fields: {
137
+ href: algolia.fields?.href?.trim() || "href",
138
+ title: algolia.fields?.title?.trim() || "title",
139
+ excerpt: algolia.fields?.excerpt?.trim() || "excerpt",
140
+ sectionTitle: algolia.fields?.sectionTitle?.trim() || "sectionTitle"
141
+ },
142
+ searchParams: algolia.searchParams ?? {}
143
+ };
144
+ };
108
145
  var normalizeAliases = (aliases, slug) => {
109
146
  const normalizedAliases = /* @__PURE__ */ new Set();
110
147
  for (const alias of aliases ?? []) {
@@ -125,7 +162,6 @@ var resolveDocsConfig = (config) => {
125
162
  const pageAliases = /* @__PURE__ */ new Set();
126
163
  const groupIds = /* @__PURE__ */ new Set();
127
164
  const sectionIds = /* @__PURE__ */ new Set();
128
- const dividerIds = /* @__PURE__ */ new Set();
129
165
  const pages = [];
130
166
  const navbarItems = [];
131
167
  const resolveSidebarNodes = (nodes, sectionId) => {
@@ -139,22 +175,12 @@ var resolveDocsConfig = (config) => {
139
175
  kind: "group",
140
176
  id: node.id,
141
177
  title: node.title,
178
+ href: node.href ? resolveNavigationHref(node.href, `group "${node.id}" href`) : void 0,
179
+ showInNav: node.showInNav ?? true,
142
180
  collapsible: node.collapsible,
143
181
  items: resolveSidebarNodes(node.items, sectionId)
144
182
  };
145
183
  }
146
- if (node.kind === "divider") {
147
- const divider = node;
148
- if (dividerIds.has(divider.id)) {
149
- throw new Error(`Duplicate docs divider id "${divider.id}".`);
150
- }
151
- dividerIds.add(divider.id);
152
- return {
153
- kind: "divider",
154
- id: divider.id,
155
- title: divider.title
156
- };
157
- }
158
184
  if (node.kind !== "page") {
159
185
  throw new Error(`Invalid docs sidebar node: ${JSON.stringify(node)}`);
160
186
  }
@@ -198,7 +224,8 @@ var resolveDocsConfig = (config) => {
198
224
  id: pageNode.id,
199
225
  title: pageNode.title,
200
226
  navTitle: pageNode.navTitle ?? pageNode.title,
201
- href
227
+ href,
228
+ showInNav: pageNode.showInNav ?? true
202
229
  };
203
230
  });
204
231
  };
@@ -211,7 +238,8 @@ var resolveDocsConfig = (config) => {
211
238
  }
212
239
  sectionIds.add(section.id);
213
240
  const items = resolveSidebarNodes(section.items, section.id);
214
- const href = getSectionHref(items);
241
+ const firstVisibleHref = getSectionHref(items, true);
242
+ const href = section.href ? resolveNavigationHref(section.href, `section "${section.id}" href`) : firstVisibleHref ?? getSectionHref(items);
215
243
  if (!href) {
216
244
  throw new Error(`Docs section "${section.id}" must contain at least one page.`);
217
245
  }
@@ -241,6 +269,7 @@ var resolveDocsConfig = (config) => {
241
269
  brand: resolveBrandConfig(config.brand, config.siteTitle),
242
270
  head: resolveHeadConfig(config.head),
243
271
  partners: resolvePartnersConfig(config.partners),
272
+ algolia: resolveAlgoliaConfig(config.algolia),
244
273
  pages,
245
274
  sections,
246
275
  navbarItems
@@ -254,7 +283,8 @@ var getResolvedPageById = (config, pageId) => {
254
283
  return page;
255
284
  };
256
285
  var getResolvedSectionById = (config, sectionId) => {
257
- return config.sections.find((section) => section.id === sectionId) ?? null;
286
+ const sections = config.sections ?? config.sidebarSections ?? [];
287
+ return sections.find((section) => section.id === sectionId) ?? null;
258
288
  };
259
289
  var getResolvedPageByPathname = (config, pathname) => {
260
290
  const normalizedPathname = normalizePathname(pathname);
@@ -280,7 +310,7 @@ var isSamePagePathname = (page, pathname) => {
280
310
  return page.aliasHrefs.some((aliasHref) => normalizePathname(aliasHref) === normalizedPathname);
281
311
  };
282
312
 
283
- // src/runtime/docHeadings.ts
313
+ // src/docs/docHeadings.ts
284
314
  var normalizeWhitespace = (value) => value.replace(/\s+/g, " ").trim();
285
315
  var slugifyHeading = (value) => {
286
316
  const normalized = normalizeWhitespace(value).normalize("NFKD").toLowerCase().replace(/['"]/g, "").replace(/[^\p{Letter}\p{Number}\s-]/gu, " ").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-+|-+$/g, "");
@@ -340,14 +370,14 @@ var extractDocHeadings = (source, minDepth = 2, maxDepth = 3) => {
340
370
  var normalizeHeadingTitle = (value) => normalizeWhitespace(value);
341
371
 
342
372
  export {
373
+ createHeadingSlugger,
374
+ extractDocHeadings,
375
+ normalizeHeadingTitle,
343
376
  resolveDocsConfig,
344
377
  getResolvedPageById,
345
378
  getResolvedSectionById,
346
379
  getResolvedPageByPathname,
347
380
  getActiveSectionByPathname,
348
- isSamePagePathname,
349
- createHeadingSlugger,
350
- extractDocHeadings,
351
- normalizeHeadingTitle
381
+ isSamePagePathname
352
382
  };
353
- //# sourceMappingURL=chunk-73NPVCDQ.js.map
383
+ //# sourceMappingURL=chunk-D7IAGT53.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/docs/resolveDocsConfig.ts","../src/docs/docHeadings.ts"],"sourcesContent":["import { nivelAssetUrl, resolvePublicAssetUrl, withSiteBaseUrl } from '../shared/assets.js'\nimport type {\n DocsAlgoliaConfig,\n DocsBrandConfig,\n DocsConfig,\n DocsFooterConfig,\n DocsHeadConfig,\n DocsPartnerConfig,\n DocsPageNode,\n DocsSectionNode,\n DocsSidebarNode,\n ResolvedDocsAlgoliaConfig,\n ResolvedDocsBrandConfig,\n ResolvedDocsConfig,\n ResolvedDocsPartnerConfig,\n ResolvedDocsPage,\n ResolvedDocsPartnersConfig,\n ResolvedDocsSection,\n ResolvedNavbarItem,\n ResolvedSidebarNode,\n ThemePreference,\n} from './types.js'\n\nconst normalizeBasePath = (value: string) => {\n const normalized = value.trim().replace(/^\\/+|\\/+$/g, '')\n return `/${normalized}` as '/docs'\n}\n\nconst normalizeSlug = (value: string) => value.replace(/^\\/+|\\/+$/g, '')\n\nconst joinHref = (basePath: '/docs', slug: string) => `${basePath}/${normalizeSlug(slug)}/`\n\nconst normalizePathname = (value: string) => {\n const pathname = value.split('?')[0]?.split('#')[0] ?? value\n const normalized = pathname.trim().replace(/\\/+$/g, '')\n return normalized === '' ? '/' : `${normalized}/`.replace(/\\/+/g, '/')\n}\n\nconst normalizeSourcePath = (value: string) => {\n const segments = value.replaceAll('\\\\', '/').split('/')\n const normalizedSegments: string[] = []\n\n for (const segment of segments) {\n if (segment === '' || segment === '.') {\n continue\n }\n\n if (segment === '..') {\n normalizedSegments.pop()\n continue\n }\n\n normalizedSegments.push(segment)\n }\n\n return normalizedSegments.join('/')\n}\n\nconst getSectionHref = (items: ResolvedSidebarNode[], visibleOnly = false): string | null => {\n for (const item of items) {\n if (item.kind === 'page') {\n if (visibleOnly && !item.showInNav) {\n continue\n }\n\n return item.href\n }\n\n if (item.kind === 'group') {\n if (visibleOnly && !item.showInNav) {\n continue\n }\n\n const href = getSectionHref(item.items, visibleOnly)\n if (href) {\n return href\n }\n }\n }\n\n return null\n}\n\nconst resolveNavigationHref = (value: string, fieldName: string) => {\n const normalized = value.trim()\n\n if (!normalized) {\n throw new Error(`Docs ${fieldName} must be a non-empty string.`)\n }\n\n return normalizePathname(normalized)\n}\n\nconst resolveThemeConfig = (theme: DocsConfig['theme']) => {\n return {\n light: theme?.light ?? 'consumer-light',\n dark: theme?.dark ?? 'consumer-dark',\n defaultPreference: (theme?.defaultPreference ?? 'light') as ThemePreference,\n }\n}\n\nconst resolveFooterConfig = (footer: DocsFooterConfig | undefined) => {\n return {\n pagination: footer?.pagination ?? false,\n }\n}\n\nconst resolveBrandConfig = (brand: DocsBrandConfig | undefined, siteTitle: string): ResolvedDocsBrandConfig => {\n const text = brand?.text ?? siteTitle\n\n return {\n text,\n href: withSiteBaseUrl(brand?.href ?? '/'),\n logoLight: resolvePublicAssetUrl(brand?.logoLight),\n logoDark: resolvePublicAssetUrl(brand?.logoDark),\n logoAlt: brand?.logoAlt ?? `${text} logo`,\n }\n}\n\nconst resolveHeadConfig = (head: DocsHeadConfig | undefined) => {\n const fontPreset = head?.fontPreset ?? 'inter'\n const defaultFontStylesheetHref = fontPreset === 'inter' ? nivelAssetUrl('fonts/fonts-inter.css') : undefined\n const defaultFontPreloadHrefs =\n fontPreset === 'inter'\n ? [\n nivelAssetUrl('fonts/inter-v20-latin-regular.woff2'),\n nivelAssetUrl('fonts/inter-v20-latin-600.woff2'),\n nivelAssetUrl('fonts/inter-v20-latin-800.woff2'),\n ]\n : []\n\n return {\n faviconSvg: resolvePublicAssetUrl(head?.faviconSvg),\n faviconIco: resolvePublicAssetUrl(head?.faviconIco),\n appleTouchIcon: resolvePublicAssetUrl(head?.appleTouchIcon),\n fontPreset,\n fontStylesheetHref: head?.fontStylesheetHref ?? defaultFontStylesheetHref,\n fontPreloadHrefs: head?.fontPreloadHrefs ?? defaultFontPreloadHrefs,\n }\n}\n\nconst resolvePartnerAssetUrl = (value: string | undefined) => {\n if (!value) {\n return undefined\n }\n\n return resolvePublicAssetUrl(value)\n}\n\nconst resolvePartner = (partner: DocsPartnerConfig): ResolvedDocsPartnerConfig => {\n return {\n name: partner.name,\n href: withSiteBaseUrl(partner.href),\n logoLight: resolvePartnerAssetUrl(partner.logoLight) ?? partner.logoLight,\n logoDark: resolvePartnerAssetUrl(partner.logoDark),\n logoAlt: partner.logoAlt ?? `${partner.name} logo`,\n }\n}\n\nconst resolvePartnersConfig = (partners: DocsConfig['partners']): ResolvedDocsPartnersConfig => {\n return {\n primary: (partners?.primary ?? []).map(resolvePartner),\n gold: (partners?.gold ?? []).map(resolvePartner),\n }\n}\n\nconst requireTrimmedString = (value: string, fieldName: string) => {\n const normalized = value.trim()\n\n if (!normalized) {\n throw new Error(`Docs algolia config \"${fieldName}\" must be a non-empty string.`)\n }\n\n return normalized\n}\n\nconst resolveAlgoliaConfig = (algolia: DocsAlgoliaConfig | undefined): ResolvedDocsAlgoliaConfig | null => {\n if (!algolia) {\n return null\n }\n\n return {\n appId: requireTrimmedString(algolia.appId, 'appId'),\n apiKey: requireTrimmedString(algolia.apiKey, 'apiKey'),\n indexName: requireTrimmedString(algolia.indexName, 'indexName'),\n fields: {\n href: algolia.fields?.href?.trim() || 'href',\n title: algolia.fields?.title?.trim() || 'title',\n excerpt: algolia.fields?.excerpt?.trim() || 'excerpt',\n sectionTitle: algolia.fields?.sectionTitle?.trim() || 'sectionTitle',\n },\n searchParams: algolia.searchParams ?? {},\n }\n}\n\nconst normalizeAliases = (aliases: string[] | undefined, slug: string) => {\n const normalizedAliases = new Set<string>()\n\n for (const alias of aliases ?? []) {\n const normalizedAlias = normalizeSlug(alias)\n if (!normalizedAlias || normalizedAlias === slug) {\n continue\n }\n\n normalizedAliases.add(normalizedAlias)\n }\n\n return [...normalizedAliases]\n}\n\nexport const resolveDocsConfig = (config: DocsConfig): ResolvedDocsConfig => {\n if (normalizeBasePath(config.basePath) !== '/docs') {\n throw new Error(`nivel currently requires basePath to be \"/docs\". Received ${JSON.stringify(config.basePath)}.`)\n }\n\n const pageIds = new Set<string>()\n const pageSlugs = new Set<string>()\n const pageAliases = new Set<string>()\n const groupIds = new Set<string>()\n const sectionIds = new Set<string>()\n const pages: ResolvedDocsPage[] = []\n const navbarItems: ResolvedNavbarItem[] = []\n\n const resolveSidebarNodes = (nodes: DocsSidebarNode[], sectionId: string): ResolvedSidebarNode[] => {\n return nodes.map((node) => {\n if (node.kind === 'group') {\n if (groupIds.has(node.id)) {\n throw new Error(`Duplicate docs group id \"${node.id}\".`)\n }\n\n groupIds.add(node.id)\n\n return {\n kind: 'group',\n id: node.id,\n title: node.title,\n href: node.href ? resolveNavigationHref(node.href, `group \"${node.id}\" href`) : undefined,\n showInNav: node.showInNav ?? true,\n collapsible: node.collapsible,\n items: resolveSidebarNodes(node.items, sectionId),\n }\n }\n\n if (node.kind !== 'page') {\n throw new Error(`Invalid docs sidebar node: ${JSON.stringify(node)}`)\n }\n\n const pageNode = node as DocsPageNode\n const slug = normalizeSlug(pageNode.slug)\n const aliases = normalizeAliases(pageNode.aliases, slug)\n\n if (!slug) {\n throw new Error(`Docs page \"${pageNode.id}\" must define a non-empty slug.`)\n }\n\n if (pageIds.has(pageNode.id)) {\n throw new Error(`Duplicate docs page id \"${pageNode.id}\".`)\n }\n\n if (pageSlugs.has(slug)) {\n throw new Error(`Duplicate docs page slug \"${slug}\".`)\n }\n\n for (const alias of aliases) {\n if (pageSlugs.has(alias) || pageAliases.has(alias)) {\n throw new Error(`Duplicate docs page alias \"${alias}\".`)\n }\n }\n\n pageIds.add(pageNode.id)\n pageSlugs.add(slug)\n for (const alias of aliases) {\n pageAliases.add(alias)\n }\n\n const href = joinHref('/docs', slug)\n const page: ResolvedDocsPage = {\n ...pageNode,\n slug,\n aliases,\n href,\n aliasHrefs: aliases.map((alias) => joinHref('/docs', alias)),\n tableOfContents: pageNode.tableOfContents ?? true,\n sectionId,\n documentTitle: `${pageNode.title} | ${config.siteTitle}`,\n source: normalizeSourcePath(pageNode.source),\n }\n pages.push(page)\n\n return {\n kind: 'page',\n id: pageNode.id,\n title: pageNode.title,\n navTitle: pageNode.navTitle ?? pageNode.title,\n href,\n showInNav: pageNode.showInNav ?? true,\n }\n })\n }\n\n const sections: ResolvedDocsSection[] = config.graph.items.map((section: DocsSectionNode) => {\n if (section.kind !== 'section') {\n throw new Error(`Top-level docs graph items must be sections. Received ${JSON.stringify(section)}`)\n }\n\n if (sectionIds.has(section.id)) {\n throw new Error(`Duplicate docs section id \"${section.id}\".`)\n }\n\n sectionIds.add(section.id)\n\n const items = resolveSidebarNodes(section.items, section.id)\n const firstVisibleHref = getSectionHref(items, true)\n const href = section.href\n ? resolveNavigationHref(section.href, `section \"${section.id}\" href`)\n : (firstVisibleHref ?? getSectionHref(items))\n\n if (!href) {\n throw new Error(`Docs section \"${section.id}\" must contain at least one page.`)\n }\n\n const resolvedSection: ResolvedDocsSection = {\n id: section.id,\n title: section.title,\n navTitle: section.navTitle ?? section.title,\n href,\n items,\n }\n\n navbarItems.push({\n id: section.id,\n title: resolvedSection.navTitle,\n href: resolvedSection.href,\n })\n\n return resolvedSection\n })\n\n if (pages.length === 0) {\n throw new Error('Docs graph must contain at least one page.')\n }\n\n return {\n siteTitle: config.siteTitle,\n siteDescription: config.siteDescription ?? null,\n basePath: '/docs',\n theme: resolveThemeConfig(config.theme),\n footer: resolveFooterConfig(config.footer),\n brand: resolveBrandConfig(config.brand, config.siteTitle),\n head: resolveHeadConfig(config.head),\n partners: resolvePartnersConfig(config.partners),\n algolia: resolveAlgoliaConfig(config.algolia),\n pages,\n sections,\n navbarItems,\n }\n}\n\nexport const getResolvedPageById = (config: { pages: ResolvedDocsPage[] }, pageId: string) => {\n const page = config.pages.find((candidate) => candidate.id === pageId)\n if (!page) {\n throw new Error(`Unknown docs page id \"${pageId}\".`)\n }\n return page\n}\n\nexport const getResolvedSectionById = (\n config: { sections?: ResolvedDocsSection[]; sidebarSections?: ResolvedDocsSection[] },\n sectionId: string,\n) => {\n const sections = config.sections ?? config.sidebarSections ?? []\n return sections.find((section) => section.id === sectionId) ?? null\n}\n\nexport const getResolvedPageByPathname = (config: { pages: ResolvedDocsPage[] }, pathname: string) => {\n const normalizedPathname = normalizePathname(pathname)\n\n return (\n config.pages.find((page) => {\n if (normalizePathname(page.href) === normalizedPathname) {\n return true\n }\n\n return page.aliasHrefs.some((aliasHref) => normalizePathname(aliasHref) === normalizedPathname)\n }) ?? null\n )\n}\n\nexport const getActiveSectionByPathname = (\n config: { pages: ResolvedDocsPage[]; sections?: ResolvedDocsSection[]; sidebarSections?: ResolvedDocsSection[] },\n pathname: string,\n) => {\n const activePage = getResolvedPageByPathname(config, pathname)\n\n if (!activePage) {\n return null\n }\n\n return getResolvedSectionById(config, activePage.sectionId)\n}\n\nexport const isSamePagePathname = (page: Pick<ResolvedDocsPage, 'href' | 'aliasHrefs'>, pathname: string) => {\n const normalizedPathname = normalizePathname(pathname)\n\n if (normalizePathname(page.href) === normalizedPathname) {\n return true\n }\n\n return page.aliasHrefs.some((aliasHref) => normalizePathname(aliasHref) === normalizedPathname)\n}\n","import type { DocHeading } from './types.js'\n\nconst normalizeWhitespace = (value: string) => value.replace(/\\s+/g, ' ').trim()\n\nconst slugifyHeading = (value: string) => {\n const normalized = normalizeWhitespace(value)\n .normalize('NFKD')\n .toLowerCase()\n .replace(/['\"]/g, '')\n .replace(/[^\\p{Letter}\\p{Number}\\s-]/gu, ' ')\n .replace(/\\s+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-+|-+$/g, '')\n\n return normalized || 'section'\n}\n\nexport const createHeadingSlugger = () => {\n const slugCounts = new Map<string, number>()\n\n return (value: string) => {\n const baseSlug = slugifyHeading(value)\n const count = slugCounts.get(baseSlug) ?? 0\n slugCounts.set(baseSlug, count + 1)\n\n return count === 0 ? baseSlug : `${baseSlug}-${count}`\n }\n}\n\nconst stripInlineMarkdown = (value: string) => {\n return normalizeWhitespace(\n value\n .replace(/!\\[([^\\]]*)\\]\\([^)]+\\)/g, '$1')\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1')\n .replace(/`([^`]+)`/g, '$1')\n .replace(/<[^>]+>/g, ' ')\n .replace(/\\\\([\\\\`*_[\\]{}()#+\\-.!])/g, '$1')\n .replace(/[*_~]/g, '')\n .replace(/\\{[^}]+\\}/g, ' '),\n )\n}\n\nconst getFenceMarker = (line: string) => {\n const match = line.match(/^\\s{0,3}(`{3,}|~{3,})/)\n return match?.[1]?.[0] ?? null\n}\n\nexport const extractDocHeadings = (source: string, minDepth = 2, maxDepth = 3): DocHeading[] => {\n const slugify = createHeadingSlugger()\n const headings: DocHeading[] = []\n let activeFenceMarker: string | null = null\n\n for (const line of source.split('\\n')) {\n const fenceMarker = getFenceMarker(line)\n\n if (activeFenceMarker) {\n if (fenceMarker === activeFenceMarker) {\n activeFenceMarker = null\n }\n continue\n }\n\n if (fenceMarker) {\n activeFenceMarker = fenceMarker\n continue\n }\n\n const match = line.match(/^\\s{0,3}(#{1,6})\\s+(.*?)(?:\\s+#+\\s*)?$/)\n if (!match) {\n continue\n }\n\n const depth = match[1].length\n const title = stripInlineMarkdown(match[2] ?? '')\n if (!title || depth < minDepth || depth > maxDepth) {\n continue\n }\n\n headings.push({\n depth,\n id: slugify(title),\n title,\n })\n }\n\n return headings\n}\n\nexport const normalizeHeadingTitle = (value: string) => normalizeWhitespace(value)\n"],"mappings":"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","names":[]}
@@ -0,0 +1,231 @@
1
+ import {
2
+ extractDocHeadings,
3
+ getResolvedPageById,
4
+ resolveDocsConfig
5
+ } from "./chunk-D7IAGT53.js";
6
+
7
+ // src/runtime/node/codegen.ts
8
+ import fs from "fs";
9
+ import path from "path";
10
+ var GENERATED_DIRNAME = "(nivel-generated)";
11
+ var writeFileIfChanged = (filePath, source) => {
12
+ const current = fs.existsSync(filePath) ? fs.readFileSync(filePath, "utf8") : null;
13
+ if (current === source) {
14
+ return;
15
+ }
16
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
17
+ fs.writeFileSync(filePath, source);
18
+ };
19
+ var toPosix = (value) => value.split(path.sep).join(path.posix.sep);
20
+ var getRelativeImportPath = (fromDirectory, toFile) => {
21
+ const relativePath = toPosix(path.relative(fromDirectory, toFile));
22
+ if (relativePath.startsWith(".")) {
23
+ return relativePath;
24
+ }
25
+ return `./${relativePath}`;
26
+ };
27
+ var serializeData = (data) => JSON.stringify(data, null, 2);
28
+ var collectFiles = (directoryPath) => {
29
+ if (!fs.existsSync(directoryPath)) {
30
+ return [];
31
+ }
32
+ const entries = fs.readdirSync(directoryPath, { withFileTypes: true });
33
+ return entries.flatMap((entry) => {
34
+ const entryPath = path.join(directoryPath, entry.name);
35
+ return entry.isDirectory() ? collectFiles(entryPath) : [entryPath];
36
+ });
37
+ };
38
+ var removeEmptyDirectories = (directoryPath, rootPath) => {
39
+ if (!fs.existsSync(directoryPath)) {
40
+ return;
41
+ }
42
+ for (const entry of fs.readdirSync(directoryPath, { withFileTypes: true })) {
43
+ if (!entry.isDirectory()) {
44
+ continue;
45
+ }
46
+ removeEmptyDirectories(path.join(directoryPath, entry.name), rootPath);
47
+ }
48
+ if (directoryPath === rootPath) {
49
+ return;
50
+ }
51
+ if (fs.readdirSync(directoryPath).length === 0) {
52
+ fs.rmdirSync(directoryPath);
53
+ }
54
+ };
55
+ var getGeneratedPageSource = (contentImportPath) => {
56
+ return [
57
+ "import { DocsPage } from '@unterberg/nivel/client'",
58
+ `import Content from ${JSON.stringify(contentImportPath)}`,
59
+ "",
60
+ "const Page = () => {",
61
+ " return <DocsPage Content={Content} />",
62
+ "}",
63
+ "",
64
+ "export default Page",
65
+ ""
66
+ ].join("\n");
67
+ };
68
+ var getGeneratedDataSource = (data) => {
69
+ return [
70
+ "import type { DocPageData } from '@unterberg/nivel'",
71
+ "",
72
+ `const data: DocPageData = ${serializeData(data)}`,
73
+ "",
74
+ "const pageData = () => {",
75
+ " return data",
76
+ "}",
77
+ "",
78
+ "export default pageData",
79
+ ""
80
+ ].join("\n");
81
+ };
82
+ var getGeneratedGlobalContextSource = (data) => {
83
+ return [
84
+ "import type { DocsGlobalContextData } from '@unterberg/nivel'",
85
+ "",
86
+ `const docsGlobalContextData: DocsGlobalContextData = ${serializeData(data)}`,
87
+ "",
88
+ "export { docsGlobalContextData }",
89
+ ""
90
+ ].join("\n");
91
+ };
92
+ var getRouteString = (href) => {
93
+ if (href === "/") {
94
+ return href;
95
+ }
96
+ return href.replace(/\/+$/g, "");
97
+ };
98
+ var getGeneratedRouteSource = (href) => {
99
+ return [`export default ${JSON.stringify(getRouteString(href))}`, ""].join("\n");
100
+ };
101
+ var getGeneratedTextExport = (value) => {
102
+ return [`export default ${JSON.stringify(value)}`, ""].join("\n");
103
+ };
104
+ var toDocPageLinkData = (page) => {
105
+ if (!page) {
106
+ return null;
107
+ }
108
+ return {
109
+ id: page.id,
110
+ title: page.title,
111
+ href: page.href,
112
+ documentTitle: page.documentTitle
113
+ };
114
+ };
115
+ var getGeneratedPagesRoot = (rootDir) => path.join(rootDir, "pages", GENERATED_DIRNAME);
116
+ var syncGeneratedDocsPages = (options) => {
117
+ const { rootDir, docsConfig } = options;
118
+ const resolved = resolveDocsConfig(docsConfig);
119
+ const generatedPagesRoot = getGeneratedPagesRoot(rootDir);
120
+ const docsRoot = path.join(rootDir, "docs");
121
+ const expectedFiles = /* @__PURE__ */ new Set();
122
+ const globalContextFilePath = path.join(generatedPagesRoot, "_docsGlobalContext.ts");
123
+ fs.mkdirSync(generatedPagesRoot, { recursive: true });
124
+ const globalContextData = {
125
+ siteTitle: resolved.siteTitle,
126
+ basePath: resolved.basePath,
127
+ theme: resolved.theme,
128
+ footer: resolved.footer,
129
+ brand: resolved.brand,
130
+ head: resolved.head,
131
+ partners: resolved.partners,
132
+ algolia: resolved.algolia,
133
+ pages: resolved.pages,
134
+ navbarItems: resolved.navbarItems,
135
+ sidebarSections: resolved.sections
136
+ };
137
+ writeFileIfChanged(globalContextFilePath, getGeneratedGlobalContextSource(globalContextData));
138
+ expectedFiles.add(globalContextFilePath);
139
+ for (const [pageIndex, page] of resolved.pages.entries()) {
140
+ const contentFilePath = path.join(docsRoot, page.source);
141
+ if (!fs.existsSync(contentFilePath)) {
142
+ throw new Error(`Docs page "${page.id}" points to missing source file: ${contentFilePath}`);
143
+ }
144
+ const pageSource = fs.readFileSync(contentFilePath, "utf8");
145
+ const data = {
146
+ page: getResolvedPageById(resolved, page.id),
147
+ headings: extractDocHeadings(pageSource),
148
+ previousPage: toDocPageLinkData(resolved.pages[pageIndex - 1]),
149
+ nextPage: toDocPageLinkData(resolved.pages[pageIndex + 1])
150
+ };
151
+ for (const routeHref of [page.href, ...page.aliasHrefs]) {
152
+ const routeSlug = routeHref.replace(/^\/docs\//, "").replace(/\/+$/g, "");
153
+ const pageDir = path.join(generatedPagesRoot, ...routeSlug.split("/"));
154
+ const contentImportPath = getRelativeImportPath(pageDir, contentFilePath);
155
+ const pageFilePath = path.join(pageDir, "+Page.tsx");
156
+ const dataFilePath = path.join(pageDir, "+data.ts");
157
+ const routeFilePath = path.join(pageDir, "+route.ts");
158
+ const titleFilePath = path.join(pageDir, "+title.ts");
159
+ writeFileIfChanged(pageFilePath, getGeneratedPageSource(contentImportPath));
160
+ writeFileIfChanged(dataFilePath, getGeneratedDataSource(data));
161
+ writeFileIfChanged(routeFilePath, getGeneratedRouteSource(routeHref));
162
+ writeFileIfChanged(titleFilePath, getGeneratedTextExport(page.documentTitle));
163
+ expectedFiles.add(pageFilePath);
164
+ expectedFiles.add(dataFilePath);
165
+ expectedFiles.add(routeFilePath);
166
+ expectedFiles.add(titleFilePath);
167
+ if (page.description) {
168
+ const descriptionFilePath = path.join(pageDir, "+description.ts");
169
+ writeFileIfChanged(descriptionFilePath, getGeneratedTextExport(page.description));
170
+ expectedFiles.add(descriptionFilePath);
171
+ }
172
+ }
173
+ }
174
+ for (const filePath of collectFiles(generatedPagesRoot)) {
175
+ if (expectedFiles.has(filePath)) {
176
+ continue;
177
+ }
178
+ fs.rmSync(filePath, { force: true });
179
+ }
180
+ removeEmptyDirectories(generatedPagesRoot, generatedPagesRoot);
181
+ };
182
+ var isDocsSourcePath = (filePath, rootDir) => {
183
+ const normalized = toPosix(filePath);
184
+ const docsRoot = toPosix(path.join(rootDir, "docs"));
185
+ const docsConfigPath = toPosix(path.join(rootDir, "pages", "+docs.ts"));
186
+ const generatedRoot = toPosix(getGeneratedPagesRoot(rootDir));
187
+ if (normalized.startsWith(generatedRoot)) {
188
+ return false;
189
+ }
190
+ return normalized === docsConfigPath || normalized.startsWith(`${docsRoot}/`);
191
+ };
192
+
193
+ // src/runtime/node/loadDocsConfig.ts
194
+ import path2 from "path";
195
+ import { pathToFileURL } from "url";
196
+ import { register } from "tsx/esm/api";
197
+ var getDocsConfigModulePath = (rootDir) => {
198
+ return path2.join(rootDir, "pages", "+docs.ts");
199
+ };
200
+ var getDocsConfigFromLoadedModule = (loaded, modulePath) => {
201
+ const docsConfig = loaded.default;
202
+ if (!docsConfig) {
203
+ throw new Error(`Expected default export from ${modulePath}`);
204
+ }
205
+ return docsConfig;
206
+ };
207
+ var loadDocsConfig = async (options) => {
208
+ const modulePath = getDocsConfigModulePath(options.rootDir);
209
+ const loaded = await options.loadModule(modulePath);
210
+ return getDocsConfigFromLoadedModule(loaded, modulePath);
211
+ };
212
+ var loadDocsConfigWithVite = async (rootDir) => {
213
+ const unregister = register();
214
+ const modulePath = getDocsConfigModulePath(rootDir);
215
+ const moduleUrl = pathToFileURL(modulePath).href;
216
+ try {
217
+ const loaded = await import(moduleUrl);
218
+ return getDocsConfigFromLoadedModule(loaded, modulePath);
219
+ } finally {
220
+ await unregister();
221
+ }
222
+ };
223
+
224
+ export {
225
+ getGeneratedPagesRoot,
226
+ syncGeneratedDocsPages,
227
+ isDocsSourcePath,
228
+ loadDocsConfig,
229
+ loadDocsConfigWithVite
230
+ };
231
+ //# sourceMappingURL=chunk-DNCQR5NH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime/node/codegen.ts","../src/runtime/node/loadDocsConfig.ts"],"sourcesContent":["import fs from 'node:fs'\nimport path from 'node:path'\nimport type { DocPageData, DocPageLinkData, DocsConfig, DocsGlobalContextData } from '../../docs/types.js'\nimport { extractDocHeadings } from '../../docs/docHeadings.js'\nimport { getResolvedPageById, resolveDocsConfig } from '../../docs/resolveDocsConfig.js'\n\nconst GENERATED_DIRNAME = '(nivel-generated)'\n\nconst writeFileIfChanged = (filePath: string, source: string) => {\n const current = fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf8') : null\n if (current === source) {\n return\n }\n\n fs.mkdirSync(path.dirname(filePath), { recursive: true })\n fs.writeFileSync(filePath, source)\n}\n\nconst toPosix = (value: string) => value.split(path.sep).join(path.posix.sep)\n\nconst getRelativeImportPath = (fromDirectory: string, toFile: string) => {\n const relativePath = toPosix(path.relative(fromDirectory, toFile))\n if (relativePath.startsWith('.')) {\n return relativePath\n }\n return `./${relativePath}`\n}\n\nconst serializeData = (data: DocPageData | DocsGlobalContextData) => JSON.stringify(data, null, 2)\n\nconst collectFiles = (directoryPath: string): string[] => {\n if (!fs.existsSync(directoryPath)) {\n return []\n }\n\n const entries = fs.readdirSync(directoryPath, { withFileTypes: true })\n\n return entries.flatMap((entry) => {\n const entryPath = path.join(directoryPath, entry.name)\n return entry.isDirectory() ? collectFiles(entryPath) : [entryPath]\n })\n}\n\nconst removeEmptyDirectories = (directoryPath: string, rootPath: string) => {\n if (!fs.existsSync(directoryPath)) {\n return\n }\n\n for (const entry of fs.readdirSync(directoryPath, { withFileTypes: true })) {\n if (!entry.isDirectory()) {\n continue\n }\n\n removeEmptyDirectories(path.join(directoryPath, entry.name), rootPath)\n }\n\n if (directoryPath === rootPath) {\n return\n }\n\n if (fs.readdirSync(directoryPath).length === 0) {\n fs.rmdirSync(directoryPath)\n }\n}\n\nconst getGeneratedPageSource = (contentImportPath: string) => {\n return [\n \"import { DocsPage } from '@unterberg/nivel/client'\",\n `import Content from ${JSON.stringify(contentImportPath)}`,\n '',\n 'const Page = () => {',\n ' return <DocsPage Content={Content} />',\n '}',\n '',\n 'export default Page',\n '',\n ].join('\\n')\n}\n\nconst getGeneratedDataSource = (data: DocPageData) => {\n return [\n \"import type { DocPageData } from '@unterberg/nivel'\",\n '',\n `const data: DocPageData = ${serializeData(data)}`,\n '',\n 'const pageData = () => {',\n ' return data',\n '}',\n '',\n 'export default pageData',\n '',\n ].join('\\n')\n}\n\nconst getGeneratedGlobalContextSource = (data: DocsGlobalContextData) => {\n return [\n \"import type { DocsGlobalContextData } from '@unterberg/nivel'\",\n '',\n `const docsGlobalContextData: DocsGlobalContextData = ${serializeData(data)}`,\n '',\n 'export { docsGlobalContextData }',\n '',\n ].join('\\n')\n}\n\nconst getRouteString = (href: string) => {\n if (href === '/') {\n return href\n }\n\n return href.replace(/\\/+$/g, '')\n}\n\nconst getGeneratedRouteSource = (href: string) => {\n return [`export default ${JSON.stringify(getRouteString(href))}`, ''].join('\\n')\n}\n\nconst getGeneratedTextExport = (value: string) => {\n return [`export default ${JSON.stringify(value)}`, ''].join('\\n')\n}\n\nconst toDocPageLinkData = (\n page:\n | {\n id: string\n title: string\n href: string\n documentTitle: string\n }\n | undefined,\n): DocPageLinkData | null => {\n if (!page) {\n return null\n }\n\n return {\n id: page.id,\n title: page.title,\n href: page.href,\n documentTitle: page.documentTitle,\n }\n}\n\nexport const getGeneratedPagesRoot = (rootDir: string) => path.join(rootDir, 'pages', GENERATED_DIRNAME)\n\nexport const syncGeneratedDocsPages = (options: { rootDir: string; docsConfig: DocsConfig }) => {\n const { rootDir, docsConfig } = options\n const resolved = resolveDocsConfig(docsConfig)\n const generatedPagesRoot = getGeneratedPagesRoot(rootDir)\n const docsRoot = path.join(rootDir, 'docs')\n const expectedFiles = new Set<string>()\n const globalContextFilePath = path.join(generatedPagesRoot, '_docsGlobalContext.ts')\n\n fs.mkdirSync(generatedPagesRoot, { recursive: true })\n\n const globalContextData: DocsGlobalContextData = {\n siteTitle: resolved.siteTitle,\n basePath: resolved.basePath,\n theme: resolved.theme,\n footer: resolved.footer,\n brand: resolved.brand,\n head: resolved.head,\n partners: resolved.partners,\n algolia: resolved.algolia,\n pages: resolved.pages,\n navbarItems: resolved.navbarItems,\n sidebarSections: resolved.sections,\n }\n\n writeFileIfChanged(globalContextFilePath, getGeneratedGlobalContextSource(globalContextData))\n expectedFiles.add(globalContextFilePath)\n\n for (const [pageIndex, page] of resolved.pages.entries()) {\n const contentFilePath = path.join(docsRoot, page.source)\n\n if (!fs.existsSync(contentFilePath)) {\n throw new Error(`Docs page \"${page.id}\" points to missing source file: ${contentFilePath}`)\n }\n\n const pageSource = fs.readFileSync(contentFilePath, 'utf8')\n const data: DocPageData = {\n page: getResolvedPageById(resolved, page.id),\n headings: extractDocHeadings(pageSource),\n previousPage: toDocPageLinkData(resolved.pages[pageIndex - 1]),\n nextPage: toDocPageLinkData(resolved.pages[pageIndex + 1]),\n }\n\n for (const routeHref of [page.href, ...page.aliasHrefs]) {\n const routeSlug = routeHref.replace(/^\\/docs\\//, '').replace(/\\/+$/g, '')\n const pageDir = path.join(generatedPagesRoot, ...routeSlug.split('/'))\n const contentImportPath = getRelativeImportPath(pageDir, contentFilePath)\n\n const pageFilePath = path.join(pageDir, '+Page.tsx')\n const dataFilePath = path.join(pageDir, '+data.ts')\n const routeFilePath = path.join(pageDir, '+route.ts')\n const titleFilePath = path.join(pageDir, '+title.ts')\n\n writeFileIfChanged(pageFilePath, getGeneratedPageSource(contentImportPath))\n writeFileIfChanged(dataFilePath, getGeneratedDataSource(data))\n writeFileIfChanged(routeFilePath, getGeneratedRouteSource(routeHref))\n writeFileIfChanged(titleFilePath, getGeneratedTextExport(page.documentTitle))\n\n expectedFiles.add(pageFilePath)\n expectedFiles.add(dataFilePath)\n expectedFiles.add(routeFilePath)\n expectedFiles.add(titleFilePath)\n\n if (page.description) {\n const descriptionFilePath = path.join(pageDir, '+description.ts')\n writeFileIfChanged(descriptionFilePath, getGeneratedTextExport(page.description))\n expectedFiles.add(descriptionFilePath)\n }\n }\n }\n\n for (const filePath of collectFiles(generatedPagesRoot)) {\n if (expectedFiles.has(filePath)) {\n continue\n }\n\n fs.rmSync(filePath, { force: true })\n }\n\n removeEmptyDirectories(generatedPagesRoot, generatedPagesRoot)\n}\n\nexport const isDocsSourcePath = (filePath: string, rootDir: string) => {\n const normalized = toPosix(filePath)\n const docsRoot = toPosix(path.join(rootDir, 'docs'))\n const docsConfigPath = toPosix(path.join(rootDir, 'pages', '+docs.ts'))\n const generatedRoot = toPosix(getGeneratedPagesRoot(rootDir))\n\n if (normalized.startsWith(generatedRoot)) {\n return false\n }\n\n return normalized === docsConfigPath || normalized.startsWith(`${docsRoot}/`)\n}\n","import path from 'node:path'\nimport { pathToFileURL } from 'node:url'\nimport { register } from 'tsx/esm/api'\nimport type { DocsConfig } from '../../docs/types.js'\n\nconst getDocsConfigModulePath = (rootDir: string) => {\n return path.join(rootDir, 'pages', '+docs.ts')\n}\n\nconst getDocsConfigFromLoadedModule = (loaded: unknown, modulePath: string) => {\n const docsConfig = (loaded as { default?: DocsConfig }).default\n\n if (!docsConfig) {\n throw new Error(`Expected default export from ${modulePath}`)\n }\n\n return docsConfig\n}\n\nexport const loadDocsConfig = async (options: {\n rootDir: string\n loadModule: (modulePath: string) => Promise<unknown>\n}) => {\n const modulePath = getDocsConfigModulePath(options.rootDir)\n const loaded = await options.loadModule(modulePath)\n return getDocsConfigFromLoadedModule(loaded, modulePath)\n}\n\nexport const loadDocsConfigWithVite = async (rootDir: string) => {\n const unregister = register()\n const modulePath = getDocsConfigModulePath(rootDir)\n const moduleUrl = pathToFileURL(modulePath).href\n\n try {\n const loaded = await import(moduleUrl)\n return getDocsConfigFromLoadedModule(loaded, modulePath)\n } finally {\n await unregister()\n }\n}\n"],"mappings":"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","names":["path"]}