@marlinjai/clearify 1.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 (80) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +81 -0
  3. package/bin/clearify.js +2 -0
  4. package/dist/node/chunk-5TD7NQIW.js +25 -0
  5. package/dist/node/chunk-B2Q23JW3.js +55 -0
  6. package/dist/node/chunk-CQ4MNGBE.js +301 -0
  7. package/dist/node/chunk-GFD54GNO.js +223 -0
  8. package/dist/node/chunk-IBK35HZR.js +194 -0
  9. package/dist/node/chunk-L24ILRSX.js +125 -0
  10. package/dist/node/chunk-NXQNNLGC.js +395 -0
  11. package/dist/node/chunk-PRTER35L.js +48 -0
  12. package/dist/node/chunk-SCZZB7OE.js +9 -0
  13. package/dist/node/chunk-V7LLYIRO.js +8 -0
  14. package/dist/node/chunk-WT5W333R.js +136 -0
  15. package/dist/node/cli/index.d.ts +2 -0
  16. package/dist/node/cli/index.js +41 -0
  17. package/dist/node/core/config.d.ts +9 -0
  18. package/dist/node/core/config.js +16 -0
  19. package/dist/node/core/mermaid-renderer.d.ts +22 -0
  20. package/dist/node/core/mermaid-renderer.js +125 -0
  21. package/dist/node/core/mermaid-utils.d.ts +3 -0
  22. package/dist/node/core/mermaid-utils.js +6 -0
  23. package/dist/node/core/navigation.d.ts +2 -0
  24. package/dist/node/core/navigation.js +13 -0
  25. package/dist/node/core/openapi-parser.d.ts +14 -0
  26. package/dist/node/core/openapi-parser.js +6 -0
  27. package/dist/node/core/remark-mermaid.d.ts +10 -0
  28. package/dist/node/core/remark-mermaid.js +11 -0
  29. package/dist/node/core/search.d.ts +31 -0
  30. package/dist/node/core/search.js +6 -0
  31. package/dist/node/node/build.d.ts +3 -0
  32. package/dist/node/node/build.js +14 -0
  33. package/dist/node/node/check.d.ts +3 -0
  34. package/dist/node/node/check.js +10 -0
  35. package/dist/node/node/index.d.ts +11 -0
  36. package/dist/node/node/index.js +108 -0
  37. package/dist/node/node/init.d.ts +6 -0
  38. package/dist/node/node/init.js +6 -0
  39. package/dist/node/presets/nestjs.d.ts +15 -0
  40. package/dist/node/presets/nestjs.js +98 -0
  41. package/dist/node/types/index.d.ts +79 -0
  42. package/dist/node/types/index.js +6 -0
  43. package/dist/node/vite-plugin/index.d.ts +13 -0
  44. package/dist/node/vite-plugin/index.js +11 -0
  45. package/package.json +94 -0
  46. package/src/client/App.tsx +101 -0
  47. package/src/client/Page.tsx +15 -0
  48. package/src/client/entry-server.tsx +79 -0
  49. package/src/client/index.html +18 -0
  50. package/src/client/main.tsx +11 -0
  51. package/src/theme/CodeBlock.tsx +103 -0
  52. package/src/theme/Content.tsx +32 -0
  53. package/src/theme/Footer.tsx +53 -0
  54. package/src/theme/Head.tsx +80 -0
  55. package/src/theme/HeadContext.tsx +32 -0
  56. package/src/theme/Header.tsx +177 -0
  57. package/src/theme/Layout.tsx +44 -0
  58. package/src/theme/MDXComponents.tsx +40 -0
  59. package/src/theme/NotFound.tsx +246 -0
  60. package/src/theme/Search.tsx +359 -0
  61. package/src/theme/Sidebar.tsx +325 -0
  62. package/src/theme/TableOfContents.tsx +153 -0
  63. package/src/theme/ThemeProvider.tsx +77 -0
  64. package/src/theme/components/Accordion.tsx +109 -0
  65. package/src/theme/components/Badge.tsx +72 -0
  66. package/src/theme/components/Breadcrumbs.tsx +88 -0
  67. package/src/theme/components/Callout.tsx +115 -0
  68. package/src/theme/components/Card.tsx +103 -0
  69. package/src/theme/components/CodeGroup.tsx +79 -0
  70. package/src/theme/components/Columns.tsx +42 -0
  71. package/src/theme/components/Frame.tsx +55 -0
  72. package/src/theme/components/Mermaid.tsx +99 -0
  73. package/src/theme/components/MermaidStatic.tsx +32 -0
  74. package/src/theme/components/OpenAPI.tsx +160 -0
  75. package/src/theme/components/OpenAPIPage.tsx +16 -0
  76. package/src/theme/components/Steps.tsx +76 -0
  77. package/src/theme/components/Tabs.tsx +75 -0
  78. package/src/theme/components/Tooltip.tsx +108 -0
  79. package/src/theme/components/index.ts +14 -0
  80. package/src/theme/styles/globals.css +363 -0
@@ -0,0 +1,223 @@
1
+ // src/node/init.ts
2
+ import { resolve } from "path";
3
+ import { existsSync, mkdirSync, writeFileSync } from "fs";
4
+ async function init(options = {}) {
5
+ const cwd = process.cwd();
6
+ const publicDir = resolve(cwd, "docs/public");
7
+ const internalDir = resolve(cwd, "docs/internal");
8
+ const configPath = resolve(cwd, "clearify.config.ts");
9
+ console.log("\n Initializing Clearify...\n");
10
+ if (!existsSync(publicDir)) {
11
+ mkdirSync(publicDir, { recursive: true });
12
+ console.log(" Created docs/public/");
13
+ } else {
14
+ console.log(" docs/public/ already exists, skipping");
15
+ }
16
+ const indexPath = resolve(publicDir, "index.md");
17
+ if (!existsSync(indexPath)) {
18
+ writeFileSync(
19
+ indexPath,
20
+ `---
21
+ title: Welcome
22
+ description: Welcome to your documentation
23
+ order: 0
24
+ ---
25
+
26
+ # Welcome
27
+
28
+ Welcome to your documentation site, powered by **Clearify**.
29
+
30
+ ## Getting Started
31
+
32
+ Edit this file at \`docs/public/index.md\` to update your home page.
33
+
34
+ ## Features
35
+
36
+ - Write docs in **Markdown** or **MDX**
37
+ - Built-in **search** across all pages
38
+ - **Dark mode** support out of the box
39
+ - **Syntax highlighting** with Shiki
40
+ - **Zero config** \u2014 just add markdown files
41
+
42
+ ## Next Steps
43
+
44
+ - Add more pages to the \`docs/public/\` folder
45
+ - Create subfolders for organized navigation
46
+ - Customize with \`clearify.config.ts\`
47
+ `
48
+ );
49
+ console.log(" Created docs/public/index.md");
50
+ }
51
+ const gettingStartedPath = resolve(publicDir, "getting-started.md");
52
+ if (!existsSync(gettingStartedPath)) {
53
+ writeFileSync(
54
+ gettingStartedPath,
55
+ `---
56
+ title: Getting Started
57
+ description: How to get started with your documentation
58
+ order: 1
59
+ ---
60
+
61
+ # Getting Started
62
+
63
+ ## Adding Pages
64
+
65
+ Create \`.md\` or \`.mdx\` files in the \`docs/public/\` folder. Each file becomes a page.
66
+
67
+ ## Organizing with Folders
68
+
69
+ Create subfolders to group related pages:
70
+
71
+ \`\`\`
72
+ docs/
73
+ \u251C\u2500\u2500 public/
74
+ \u2502 \u251C\u2500\u2500 index.md # Home page
75
+ \u2502 \u251C\u2500\u2500 getting-started.md # This page
76
+ \u2502 \u2514\u2500\u2500 guides/
77
+ \u2502 \u251C\u2500\u2500 installation.md
78
+ \u2502 \u2514\u2500\u2500 configuration.md
79
+ \u2514\u2500\u2500 internal/ # Design docs, roadmaps
80
+ \u2514\u2500\u2500 index.md
81
+ \`\`\`
82
+
83
+ Folders automatically become navigation groups.
84
+
85
+ ## Frontmatter
86
+
87
+ Control page metadata with frontmatter:
88
+
89
+ \`\`\`yaml
90
+ ---
91
+ title: My Page Title
92
+ description: A brief description
93
+ order: 1
94
+ ---
95
+ \`\`\`
96
+
97
+ ## Running the Dev Server
98
+
99
+ \`\`\`bash
100
+ npx clearify dev
101
+ \`\`\`
102
+
103
+ ## Building for Production
104
+
105
+ \`\`\`bash
106
+ npx clearify build
107
+ \`\`\`
108
+
109
+ This outputs a static site to \`docs-dist/\`.
110
+ `
111
+ );
112
+ console.log(" Created docs/public/getting-started.md");
113
+ }
114
+ if (!options.noInternal) {
115
+ if (!existsSync(internalDir)) {
116
+ mkdirSync(internalDir, { recursive: true });
117
+ console.log(" Created docs/internal/");
118
+ } else {
119
+ console.log(" docs/internal/ already exists, skipping");
120
+ }
121
+ const internalIndexPath = resolve(internalDir, "index.md");
122
+ if (!existsSync(internalIndexPath)) {
123
+ writeFileSync(
124
+ internalIndexPath,
125
+ `---
126
+ title: Internal Docs
127
+ description: Internal documentation \u2014 design docs, roadmaps, and architecture
128
+ order: 0
129
+ ---
130
+
131
+ # Internal Docs
132
+
133
+ This section is for internal documentation that isn't published to your public site.
134
+
135
+ ## What goes here?
136
+
137
+ - **Design documents** \u2014 technical designs and proposals
138
+ - **Roadmaps** \u2014 planned features and milestones
139
+ - **Architecture decisions** \u2014 ADRs and context for past choices
140
+ - **Meeting notes** \u2014 decisions and action items
141
+
142
+ > This section is marked as \`draft\` and won't be included in production builds.
143
+ `
144
+ );
145
+ console.log(" Created docs/internal/index.md");
146
+ }
147
+ }
148
+ const changelogPath = resolve(cwd, "CHANGELOG.md");
149
+ if (!existsSync(changelogPath)) {
150
+ const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
151
+ writeFileSync(
152
+ changelogPath,
153
+ `# Changelog
154
+
155
+ All notable changes to this project will be documented in this file.
156
+
157
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
158
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
159
+
160
+ ## [Unreleased]
161
+
162
+ ## [0.1.0] - ${today}
163
+
164
+ ### Added
165
+
166
+ - Initial project setup
167
+ - Documentation site powered by Clearify
168
+ `
169
+ );
170
+ console.log(" Created CHANGELOG.md");
171
+ } else {
172
+ console.log(" CHANGELOG.md already exists, skipping");
173
+ }
174
+ if (!existsSync(configPath)) {
175
+ if (options.noInternal) {
176
+ writeFileSync(
177
+ configPath,
178
+ `import { defineConfig } from 'clearify';
179
+
180
+ export default defineConfig({
181
+ name: 'My Documentation',
182
+ docsDir: './docs/public',
183
+ theme: {
184
+ primaryColor: '#3B82F6',
185
+ mode: 'auto',
186
+ },
187
+ });
188
+ `
189
+ );
190
+ } else {
191
+ writeFileSync(
192
+ configPath,
193
+ `import { defineConfig } from 'clearify';
194
+
195
+ export default defineConfig({
196
+ name: 'My Documentation',
197
+ sections: [
198
+ { label: 'Docs', docsDir: './docs/public' },
199
+ { label: 'Internal', docsDir: './docs/internal', basePath: '/internal', draft: true },
200
+ ],
201
+ theme: {
202
+ primaryColor: '#3B82F6',
203
+ mode: 'auto',
204
+ },
205
+ });
206
+ `
207
+ );
208
+ }
209
+ console.log(" Created clearify.config.ts");
210
+ } else {
211
+ console.log(" clearify.config.ts already exists, skipping");
212
+ }
213
+ console.log(`
214
+ Done! Next steps:
215
+
216
+ npx clearify dev Start the dev server
217
+ npx clearify build Build for production
218
+ `);
219
+ }
220
+
221
+ export {
222
+ init
223
+ };
@@ -0,0 +1,194 @@
1
+ // src/core/config.ts
2
+ import { z } from "zod";
3
+ import { resolve, basename } from "path";
4
+ import { pathToFileURL } from "url";
5
+ import { existsSync, readFileSync, rmSync } from "fs";
6
+ import { tmpdir } from "os";
7
+ import { randomBytes } from "crypto";
8
+ var NavigationItemSchema = z.lazy(
9
+ () => z.object({
10
+ label: z.string(),
11
+ path: z.string().optional(),
12
+ icon: z.string().optional(),
13
+ badge: z.string().optional(),
14
+ badgeColor: z.string().optional(),
15
+ children: z.array(NavigationItemSchema).optional()
16
+ })
17
+ );
18
+ var SectionConfigSchema = z.object({
19
+ label: z.string(),
20
+ docsDir: z.string(),
21
+ basePath: z.string().optional(),
22
+ draft: z.boolean().optional(),
23
+ sitemap: z.boolean().optional(),
24
+ exclude: z.array(z.string()).optional()
25
+ });
26
+ var MermaidConfigSchema = z.object({
27
+ strategy: z.enum(["client", "build"]).default("client")
28
+ }).default({ strategy: "client" });
29
+ var OpenAPIConfigSchema = z.object({
30
+ spec: z.string(),
31
+ basePath: z.string().default("/api"),
32
+ generatePages: z.boolean().default(true)
33
+ }).optional();
34
+ var ClearifyConfigSchema = z.object({
35
+ name: z.string().default("Documentation"),
36
+ docsDir: z.string().default("./docs"),
37
+ outDir: z.string().default("./docs-dist"),
38
+ port: z.number().default(4747),
39
+ siteUrl: z.string().optional(),
40
+ theme: z.object({
41
+ primaryColor: z.string().default("#3B82F6"),
42
+ mode: z.enum(["light", "dark", "auto"]).default("auto")
43
+ }).default({ primaryColor: "#3B82F6", mode: "auto" }),
44
+ logo: z.object({
45
+ light: z.string().optional(),
46
+ dark: z.string().optional()
47
+ }).optional(),
48
+ sections: z.array(SectionConfigSchema).optional(),
49
+ navigation: z.array(NavigationItemSchema).nullable().default(null),
50
+ exclude: z.array(z.string()).default([]),
51
+ mermaid: MermaidConfigSchema,
52
+ openapi: OpenAPIConfigSchema,
53
+ links: z.record(z.string(), z.string()).optional(),
54
+ customCss: z.string().optional(),
55
+ headTags: z.array(z.string()).optional()
56
+ });
57
+ var defaultConfig = {
58
+ name: "Documentation",
59
+ docsDir: "./docs",
60
+ outDir: "./docs-dist",
61
+ port: 4747,
62
+ theme: {
63
+ primaryColor: "#3B82F6",
64
+ mode: "auto"
65
+ },
66
+ navigation: null
67
+ };
68
+ function detectProjectName(root) {
69
+ const pkgPath = resolve(root, "package.json");
70
+ if (existsSync(pkgPath)) {
71
+ try {
72
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
73
+ if (pkg.name) {
74
+ const raw = pkg.name.replace(/^@[^/]+\//, "");
75
+ return raw.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
76
+ }
77
+ } catch {
78
+ }
79
+ }
80
+ const dirName = basename(root);
81
+ return dirName.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
82
+ }
83
+ async function loadTsConfig(configPath) {
84
+ const { build } = await import("esbuild");
85
+ const tmpId = randomBytes(4).toString("hex");
86
+ const outFile = resolve(tmpdir(), `clearify-config-${tmpId}.mjs`);
87
+ try {
88
+ await build({
89
+ entryPoints: [configPath],
90
+ outfile: outFile,
91
+ bundle: true,
92
+ format: "esm",
93
+ platform: "node",
94
+ write: true,
95
+ // Bundle the clearify import (defineConfig is a trivial identity fn),
96
+ // but keep everything else external so we don't pull in user deps.
97
+ plugins: [{
98
+ name: "externalize-except-clearify",
99
+ setup(build2) {
100
+ build2.onResolve({ filter: /.*/ }, (args) => {
101
+ if (args.path.startsWith(".") || args.path.startsWith("/") || args.path === "clearify") {
102
+ return void 0;
103
+ }
104
+ return { path: args.path, external: true };
105
+ });
106
+ }
107
+ }]
108
+ });
109
+ const mod = await import(pathToFileURL(outFile).href);
110
+ return mod.default ?? mod;
111
+ } finally {
112
+ try {
113
+ rmSync(outFile, { force: true });
114
+ } catch {
115
+ }
116
+ }
117
+ }
118
+ async function loadUserConfig(root) {
119
+ const configFiles = [
120
+ "clearify.config.ts",
121
+ "clearify.config.js",
122
+ "clearify.config.mjs"
123
+ ];
124
+ for (const file of configFiles) {
125
+ const configPath = resolve(root, file);
126
+ if (existsSync(configPath)) {
127
+ try {
128
+ if (file.endsWith(".ts")) {
129
+ return await loadTsConfig(configPath);
130
+ }
131
+ const mod = await import(pathToFileURL(configPath).href);
132
+ return mod.default ?? mod;
133
+ } catch {
134
+ }
135
+ }
136
+ }
137
+ return {};
138
+ }
139
+ function resolveConfig(userConfig = {}, root) {
140
+ const parsed = ClearifyConfigSchema.parse(userConfig);
141
+ if (!userConfig.name && root) {
142
+ parsed.name = detectProjectName(root);
143
+ }
144
+ return parsed;
145
+ }
146
+ function slugify(str) {
147
+ return str.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
148
+ }
149
+ function resolveSections(config, root) {
150
+ if (config.sections && config.sections.length > 0) {
151
+ const sections = config.sections.map((s, i) => {
152
+ const id = slugify(s.label);
153
+ const draft = s.draft ?? false;
154
+ const basePath = s.basePath ?? (i === 0 ? "/" : "/" + id);
155
+ const sitemap = s.sitemap ?? !draft;
156
+ const exclude = [...config.exclude ?? [], ...s.exclude ?? []];
157
+ return {
158
+ id,
159
+ label: s.label,
160
+ docsDir: resolve(root, s.docsDir),
161
+ basePath,
162
+ draft,
163
+ sitemap,
164
+ exclude
165
+ };
166
+ });
167
+ const seen = /* @__PURE__ */ new Set();
168
+ for (const s of sections) {
169
+ if (seen.has(s.basePath)) {
170
+ throw new Error(`Duplicate section basePath: "${s.basePath}"`);
171
+ }
172
+ seen.add(s.basePath);
173
+ }
174
+ return sections;
175
+ }
176
+ return [
177
+ {
178
+ id: "default",
179
+ label: config.name,
180
+ docsDir: resolve(root, config.docsDir),
181
+ basePath: "/",
182
+ draft: false,
183
+ sitemap: true,
184
+ exclude: config.exclude ?? []
185
+ }
186
+ ];
187
+ }
188
+
189
+ export {
190
+ defaultConfig,
191
+ loadUserConfig,
192
+ resolveConfig,
193
+ resolveSections
194
+ };
@@ -0,0 +1,125 @@
1
+ import {
2
+ buildSearchIndex
3
+ } from "./chunk-5TD7NQIW.js";
4
+
5
+ // src/core/navigation.ts
6
+ import { resolve, relative, basename, dirname, extname } from "path";
7
+ import { readFileSync, existsSync } from "fs";
8
+ import matter from "gray-matter";
9
+ import { globbySync } from "globby";
10
+ function toTitleCase(str) {
11
+ return str.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
12
+ }
13
+ function fileToRoutePath(filePath, docsDir, basePath = "/") {
14
+ const rel = relative(docsDir, filePath);
15
+ const ext = extname(rel);
16
+ const withoutExt = rel.slice(0, -ext.length);
17
+ let routePath;
18
+ if (withoutExt === "index") routePath = "/";
19
+ else if (withoutExt.endsWith("/index")) routePath = "/" + withoutExt.slice(0, -"/index".length);
20
+ else routePath = "/" + withoutExt;
21
+ if (basePath === "/") return routePath;
22
+ const prefix = basePath.replace(/\/$/, "");
23
+ return routePath === "/" ? prefix : prefix + routePath;
24
+ }
25
+ function scanDocs(docsDir, exclude = [], basePath = "/") {
26
+ const absDocsDir = resolve(docsDir);
27
+ const files = globbySync("**/*.{md,mdx}", {
28
+ cwd: absDocsDir,
29
+ ignore: ["**/node_modules/**", "**/_*", "**/_*/**", ...exclude],
30
+ absolute: true
31
+ });
32
+ return files.map((filePath) => {
33
+ const content = readFileSync(filePath, "utf-8");
34
+ const { data } = matter(content);
35
+ const routePath = fileToRoutePath(filePath, absDocsDir, basePath);
36
+ return {
37
+ filePath,
38
+ routePath,
39
+ frontmatter: {
40
+ title: data.title ?? toTitleCase(basename(filePath, extname(filePath))),
41
+ description: data.description,
42
+ icon: data.icon,
43
+ order: data.order
44
+ }
45
+ };
46
+ });
47
+ }
48
+ function buildNavigation(docs, basePath = "/") {
49
+ const rootDir = basePath === "/" ? "/" : basePath.replace(/\/$/, "");
50
+ const groups = /* @__PURE__ */ new Map();
51
+ for (const doc of docs) {
52
+ const dir = dirname(doc.routePath);
53
+ if (!groups.has(dir)) groups.set(dir, []);
54
+ groups.get(dir).push(doc);
55
+ }
56
+ for (const files of groups.values()) {
57
+ files.sort((a, b) => {
58
+ const orderA = a.frontmatter.order ?? 999;
59
+ const orderB = b.frontmatter.order ?? 999;
60
+ if (orderA !== orderB) return orderA - orderB;
61
+ return a.routePath.localeCompare(b.routePath);
62
+ });
63
+ }
64
+ const nav = [];
65
+ const rootFiles = groups.get(rootDir) ?? [];
66
+ for (const doc of rootFiles) {
67
+ if (doc.routePath === rootDir || doc.routePath === "/") continue;
68
+ const item = { label: doc.frontmatter.title, path: doc.routePath };
69
+ if (doc.frontmatter.icon) item.icon = doc.frontmatter.icon;
70
+ nav.push(item);
71
+ }
72
+ const dirs = [...groups.keys()].filter((d) => d !== rootDir).sort();
73
+ for (const dir of dirs) {
74
+ const files = groups.get(dir);
75
+ const label = toTitleCase(basename(dir));
76
+ const children = files.map((doc) => {
77
+ const child = { label: doc.frontmatter.title, path: doc.routePath };
78
+ if (doc.frontmatter.icon) child.icon = doc.frontmatter.icon;
79
+ return child;
80
+ });
81
+ nav.push({ label, children });
82
+ }
83
+ return nav;
84
+ }
85
+ function buildRoutes(docs, sectionId) {
86
+ return docs.map((doc) => ({
87
+ path: doc.routePath,
88
+ filePath: doc.filePath,
89
+ frontmatter: doc.frontmatter,
90
+ ...sectionId ? { sectionId } : {}
91
+ }));
92
+ }
93
+ function buildSectionData(section, changelogPath, customNavigation) {
94
+ const docs = scanDocs(section.docsDir, section.exclude, section.basePath);
95
+ if (section.basePath === "/" && changelogPath && existsSync(changelogPath)) {
96
+ const content = readFileSync(changelogPath, "utf-8");
97
+ const { data } = matter(content);
98
+ docs.push({
99
+ filePath: changelogPath,
100
+ routePath: "/changelog",
101
+ frontmatter: {
102
+ title: data.title ?? "Changelog",
103
+ description: data.description ?? "Release history",
104
+ order: 9999
105
+ }
106
+ });
107
+ }
108
+ const nav = section.basePath === "/" && customNavigation ? customNavigation : buildNavigation(docs, section.basePath);
109
+ const navigation = {
110
+ id: section.id,
111
+ label: section.label,
112
+ basePath: section.basePath,
113
+ navigation: nav
114
+ };
115
+ const routes = buildRoutes(docs, section.id);
116
+ const searchEntries = buildSearchIndex(docs, section.id, section.label);
117
+ return { section, docs, navigation, routes, searchEntries };
118
+ }
119
+
120
+ export {
121
+ scanDocs,
122
+ buildNavigation,
123
+ buildRoutes,
124
+ buildSectionData
125
+ };