@rodavel/vite-plugin-content-tree 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +66 -0
- package/dist/index.cjs +537 -0
- package/dist/index.d.cts +277 -0
- package/dist/index.d.ts +277 -0
- package/dist/index.js +484 -0
- package/package.json +71 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
|
|
3
|
+
declare const INDEX_SUFFIX = "/index";
|
|
4
|
+
declare const DEFAULT_META_FILE = "_meta.json";
|
|
5
|
+
declare const DEFAULT_PAGE_FILE = "index.mdx";
|
|
6
|
+
declare const DEFAULT_ORDER = 999;
|
|
7
|
+
|
|
8
|
+
/** Index page associated with a directory node. */
|
|
9
|
+
interface ContentTreeIndexNode {
|
|
10
|
+
type: "page";
|
|
11
|
+
name: string;
|
|
12
|
+
url: string;
|
|
13
|
+
id: string;
|
|
14
|
+
}
|
|
15
|
+
/** A page node in the content tree. */
|
|
16
|
+
interface ContentTreePageNode {
|
|
17
|
+
type: "page";
|
|
18
|
+
name: string;
|
|
19
|
+
id: string;
|
|
20
|
+
url: string;
|
|
21
|
+
order: number;
|
|
22
|
+
}
|
|
23
|
+
/** A directory node in the content tree. */
|
|
24
|
+
interface ContentTreeDirectoryNode {
|
|
25
|
+
type: "directory";
|
|
26
|
+
name: string;
|
|
27
|
+
id: string;
|
|
28
|
+
children: ContentTreeNode[];
|
|
29
|
+
index?: ContentTreeIndexNode;
|
|
30
|
+
order: number;
|
|
31
|
+
}
|
|
32
|
+
/** A node in the content tree — either a page or a directory. */
|
|
33
|
+
type ContentTreeNode = ContentTreePageNode | ContentTreeDirectoryNode;
|
|
34
|
+
/** Recursive type that strips the `order` field from a tree node and its descendants. */
|
|
35
|
+
type WithoutOrder = {
|
|
36
|
+
type: "page";
|
|
37
|
+
name: string;
|
|
38
|
+
id: string;
|
|
39
|
+
url: string;
|
|
40
|
+
} | {
|
|
41
|
+
type: "directory";
|
|
42
|
+
name: string;
|
|
43
|
+
id: string;
|
|
44
|
+
children: WithoutOrder[];
|
|
45
|
+
index?: ContentTreeIndexNode;
|
|
46
|
+
};
|
|
47
|
+
/** Minimal frontmatter fields used by the core scanning logic. */
|
|
48
|
+
interface BaseFrontmatter {
|
|
49
|
+
title: string;
|
|
50
|
+
description?: string;
|
|
51
|
+
order?: number;
|
|
52
|
+
nav?: string;
|
|
53
|
+
}
|
|
54
|
+
/** What a `mapFrontmatter` callback must return. */
|
|
55
|
+
interface FrontmatterResult {
|
|
56
|
+
title: string;
|
|
57
|
+
description?: string;
|
|
58
|
+
nav?: string;
|
|
59
|
+
order?: number;
|
|
60
|
+
/** Arbitrary extra fields that flow into `ScannedPage.extra`. */
|
|
61
|
+
extra?: Record<string, unknown>;
|
|
62
|
+
}
|
|
63
|
+
/** A parsed content page with extracted metadata. */
|
|
64
|
+
interface ScannedPage {
|
|
65
|
+
key: string;
|
|
66
|
+
title: string;
|
|
67
|
+
description?: string;
|
|
68
|
+
nav?: string;
|
|
69
|
+
order: number;
|
|
70
|
+
file: string;
|
|
71
|
+
segments: string[];
|
|
72
|
+
extra?: Record<string, unknown>;
|
|
73
|
+
}
|
|
74
|
+
/** Metadata read from a directory's `_meta.json` file. */
|
|
75
|
+
interface DirectoryMeta {
|
|
76
|
+
name?: string;
|
|
77
|
+
order?: number;
|
|
78
|
+
/** Arbitrary extra fields from the metadata file that aren't part of the base schema. */
|
|
79
|
+
extra?: Record<string, unknown>;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Resolves the display label for a directory node in the content tree.
|
|
83
|
+
*
|
|
84
|
+
* @param dirName - The raw directory name (slug)
|
|
85
|
+
* @param meta - Parsed metadata from the directory's `_meta.json` file
|
|
86
|
+
* @param indexPage - The index page for this directory, if one exists
|
|
87
|
+
* @param acronyms - Set of words to fully uppercase when humanizing
|
|
88
|
+
* @returns The display label for the directory node
|
|
89
|
+
*/
|
|
90
|
+
type DirectoryLabelResolver = (dirName: string, meta: DirectoryMeta, indexPage: ScannedPage | undefined, acronyms: Set<string>) => string;
|
|
91
|
+
/**
|
|
92
|
+
* Maps raw frontmatter data to the fields used by the content tree.
|
|
93
|
+
*
|
|
94
|
+
* @param raw - The parsed frontmatter object from gray-matter
|
|
95
|
+
* @param file - The relative file path (for error messages or conditional logic)
|
|
96
|
+
* @returns The extracted frontmatter fields
|
|
97
|
+
*/
|
|
98
|
+
type FrontmatterMapper = (raw: Record<string, unknown>, file: string) => FrontmatterResult;
|
|
99
|
+
/**
|
|
100
|
+
* Post-processes scanned pages before tree building.
|
|
101
|
+
* Use this to enrich pages with computed fields (e.g., resolving module names from ancestors).
|
|
102
|
+
*/
|
|
103
|
+
type PageEnricher = (pages: ScannedPage[], pageByKey: Map<string, ScannedPage>) => void;
|
|
104
|
+
/**
|
|
105
|
+
* Maps a scanned page to the object shape written to the generated output file.
|
|
106
|
+
* The returned object is serialized as a value in the `pages` Map.
|
|
107
|
+
*/
|
|
108
|
+
type PageEntryMapper = (page: ScannedPage) => Record<string, unknown>;
|
|
109
|
+
/** Configuration for the content tree generator. */
|
|
110
|
+
interface ContentTreeGeneratorOptions {
|
|
111
|
+
/** Path to the content directory to scan. */
|
|
112
|
+
docsDir: string;
|
|
113
|
+
/** Path where the generated TypeScript file is written. */
|
|
114
|
+
outFile: string;
|
|
115
|
+
/** URL prefix prepended to page paths (e.g., `"/docs"`). */
|
|
116
|
+
urlPrefix: string;
|
|
117
|
+
/** Display name for the root tree object (e.g., `"Docs"`). */
|
|
118
|
+
treeName: string;
|
|
119
|
+
/** If provided, wraps top-level children in a synthetic root directory node. */
|
|
120
|
+
root?: {
|
|
121
|
+
name: string;
|
|
122
|
+
id: string;
|
|
123
|
+
};
|
|
124
|
+
/** Type to import in the generated file for the tree variable. */
|
|
125
|
+
treeType?: {
|
|
126
|
+
from: string;
|
|
127
|
+
name: string;
|
|
128
|
+
};
|
|
129
|
+
/** Type to import in the generated file for the pages Map values. */
|
|
130
|
+
pageType?: {
|
|
131
|
+
from: string;
|
|
132
|
+
name: string;
|
|
133
|
+
};
|
|
134
|
+
/** Export name for the pages Map. @default "pages" */
|
|
135
|
+
pagesExportName?: string;
|
|
136
|
+
/** Export name for the tree object. @default "docsTree" */
|
|
137
|
+
treeExportName?: string;
|
|
138
|
+
/** Acronyms to uppercase when humanizing directory names. */
|
|
139
|
+
acronyms?: string[] | Set<string>;
|
|
140
|
+
/** Filename for directory metadata. @default "_meta.json" */
|
|
141
|
+
metaFile?: string;
|
|
142
|
+
/** Filename to match as a page entry. @default "index.mdx" */
|
|
143
|
+
pageFile?: string;
|
|
144
|
+
/** Custom frontmatter mapper. The default handles `BaseFrontmatter` fields plus `module` in `extra`. */
|
|
145
|
+
mapFrontmatter?: FrontmatterMapper;
|
|
146
|
+
/**
|
|
147
|
+
* Post-processes pages after scanning.
|
|
148
|
+
* @default no-op — pass `resolveModules` to enable module resolution from ancestors.
|
|
149
|
+
*/
|
|
150
|
+
enrichPages?: PageEnricher;
|
|
151
|
+
/** Customizes the per-page entry shape in the generated output. */
|
|
152
|
+
mapPageEntry?: PageEntryMapper;
|
|
153
|
+
/**
|
|
154
|
+
* Resolves the display label for directory nodes.
|
|
155
|
+
* @default Falls back to `extra.module` → `meta.name` → `humanize(dirName)`.
|
|
156
|
+
*/
|
|
157
|
+
resolveDirectoryLabel?: DirectoryLabelResolver;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
interface GenerateDataResult {
|
|
161
|
+
pages: ScannedPage[];
|
|
162
|
+
tree: WithoutOrder;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Runs the full scan → enrich → build pipeline and returns the raw data
|
|
166
|
+
* without writing any files.
|
|
167
|
+
*
|
|
168
|
+
* @param opts - Generator configuration
|
|
169
|
+
* @returns The scanned pages and the built tree (with order fields stripped)
|
|
170
|
+
*/
|
|
171
|
+
declare function generateData(opts: ContentTreeGeneratorOptions): Promise<GenerateDataResult>;
|
|
172
|
+
/**
|
|
173
|
+
* Writes the generated data to a TypeScript file using the configured template.
|
|
174
|
+
*
|
|
175
|
+
* @param opts - Generator configuration (controls export names, type imports, page entry shape)
|
|
176
|
+
* @param data - The data to serialize (from `generateData`)
|
|
177
|
+
*/
|
|
178
|
+
declare function writeOutput(opts: ContentTreeGeneratorOptions, data: GenerateDataResult): Promise<void>;
|
|
179
|
+
/**
|
|
180
|
+
* Generates the content tree data and writes it to the configured output file.
|
|
181
|
+
*
|
|
182
|
+
* @param opts - Generator configuration
|
|
183
|
+
*/
|
|
184
|
+
declare function generate(opts: ContentTreeGeneratorOptions): Promise<void>;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Vite plugin that scans a content directory, extracts frontmatter,
|
|
188
|
+
* and generates a typed navigation tree + page index as a TypeScript file.
|
|
189
|
+
*
|
|
190
|
+
* Runs at build start and watches for changes during dev.
|
|
191
|
+
*
|
|
192
|
+
* @param opts - Generator configuration
|
|
193
|
+
* @returns A Vite plugin
|
|
194
|
+
*/
|
|
195
|
+
declare function contentTreeGeneratorPlugin(opts: ContentTreeGeneratorOptions): Plugin;
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Default frontmatter mapper that extracts base fields and passes
|
|
199
|
+
* all remaining fields through as `extra`.
|
|
200
|
+
*/
|
|
201
|
+
declare const defaultMapFrontmatter: FrontmatterMapper;
|
|
202
|
+
/**
|
|
203
|
+
* Reads and parses a directory metadata file (e.g., `_meta.json`).
|
|
204
|
+
*
|
|
205
|
+
* @param docsDir - Root content directory path
|
|
206
|
+
* @param dirPath - Relative path to the directory within docsDir
|
|
207
|
+
* @param metaFile - Name of the metadata file to look for
|
|
208
|
+
* @returns Parsed metadata or an empty object if the file doesn't exist
|
|
209
|
+
*/
|
|
210
|
+
declare function readDirectoryMeta(docsDir: string, dirPath: string, metaFile: string): Promise<DirectoryMeta>;
|
|
211
|
+
/**
|
|
212
|
+
* Recursively scans a content directory for page files, extracts frontmatter,
|
|
213
|
+
* and returns an array of scanned pages.
|
|
214
|
+
*
|
|
215
|
+
* @param docsDir - Root content directory to scan
|
|
216
|
+
* @param pageFile - Filename to match as a page entry (e.g., `"index.mdx"`)
|
|
217
|
+
* @param mapFrontmatter - Callback to extract fields from raw frontmatter data
|
|
218
|
+
* @returns Array of scanned pages with extracted metadata
|
|
219
|
+
*/
|
|
220
|
+
declare function scanPages(docsDir: string, pageFile: string, mapFrontmatter?: FrontmatterMapper): Promise<ScannedPage[]>;
|
|
221
|
+
/**
|
|
222
|
+
* Resolves the `extra.module` field for each page by looking up its module-root ancestor.
|
|
223
|
+
* Pages inherit the module from the root page of their first path segment.
|
|
224
|
+
*
|
|
225
|
+
* This is the default `enrichPages` implementation.
|
|
226
|
+
*/
|
|
227
|
+
declare function resolveModules(pages: ScannedPage[], pageByKey: Map<string, ScannedPage>): void;
|
|
228
|
+
|
|
229
|
+
/** Pre-computed index that groups pages by parent path for O(1) lookups during tree building. */
|
|
230
|
+
interface PageIndex {
|
|
231
|
+
directChildren: Map<string, ScannedPage[]>;
|
|
232
|
+
subDirNames: Map<string, Set<string>>;
|
|
233
|
+
}
|
|
234
|
+
/** Context threaded through recursive `buildChildren` calls. */
|
|
235
|
+
interface BuildContext {
|
|
236
|
+
pageIndex: PageIndex;
|
|
237
|
+
metas: Map<string, DirectoryMeta>;
|
|
238
|
+
urlPrefix: string;
|
|
239
|
+
acronyms: Set<string>;
|
|
240
|
+
resolveDirectoryLabel: DirectoryLabelResolver;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Pre-groups pages into a lookup index so `buildChildren` can avoid
|
|
244
|
+
* re-filtering the full page list at every recursion level.
|
|
245
|
+
*
|
|
246
|
+
* @param pages - All scanned pages (root page with key="" is excluded from grouping)
|
|
247
|
+
* @returns A `PageIndex` with O(1) lookups by parent path
|
|
248
|
+
*/
|
|
249
|
+
declare function buildPageIndex(pages: ScannedPage[]): PageIndex;
|
|
250
|
+
/**
|
|
251
|
+
* Converts a kebab-case slug to Title Case, uppercasing known acronyms.
|
|
252
|
+
*
|
|
253
|
+
* @param slug - The slug to humanize (e.g., `"ses-api-reference"`)
|
|
254
|
+
* @param acronyms - Set of words to fully uppercase (e.g., `"ses"` → `"SES"`)
|
|
255
|
+
* @returns The humanized string (e.g., `"SES API Reference"`)
|
|
256
|
+
*/
|
|
257
|
+
declare function humanize(slug: string, acronyms: Set<string>): string;
|
|
258
|
+
/**
|
|
259
|
+
* Default directory label resolver.
|
|
260
|
+
* Falls back through: `extra.module` → `meta.name` → `humanize(dirName)`.
|
|
261
|
+
*/
|
|
262
|
+
declare const defaultResolveDirectoryLabel: DirectoryLabelResolver;
|
|
263
|
+
/**
|
|
264
|
+
* Recursively builds a sorted array of child nodes for a given parent path.
|
|
265
|
+
*
|
|
266
|
+
* @param parentPath - The key prefix for the parent (empty string for root)
|
|
267
|
+
* @param ctx - Build context with shared configuration and pre-scanned metadata
|
|
268
|
+
* @returns Sorted array of tree nodes
|
|
269
|
+
*/
|
|
270
|
+
declare function buildChildren(parentPath: string, ctx: BuildContext): ContentTreeNode[];
|
|
271
|
+
/**
|
|
272
|
+
* Recursively removes the `order` field from a tree node and all its descendants.
|
|
273
|
+
* The `order` field is only used for sorting and is not needed in the final output.
|
|
274
|
+
*/
|
|
275
|
+
declare function stripOrder(node: ContentTreeNode): WithoutOrder;
|
|
276
|
+
|
|
277
|
+
export { type BaseFrontmatter, type BuildContext, type ContentTreeDirectoryNode, type ContentTreeGeneratorOptions, type ContentTreeIndexNode, type ContentTreeNode, type ContentTreePageNode, DEFAULT_META_FILE, DEFAULT_ORDER, DEFAULT_PAGE_FILE, type DirectoryLabelResolver, type DirectoryMeta, type FrontmatterMapper, type FrontmatterResult, type GenerateDataResult, INDEX_SUFFIX, type PageEnricher, type PageEntryMapper, type PageIndex, type ScannedPage, type WithoutOrder, buildChildren, buildPageIndex, contentTreeGeneratorPlugin, defaultMapFrontmatter, defaultResolveDirectoryLabel, generate, generateData, humanize, readDirectoryMeta, resolveModules, scanPages, stripOrder, writeOutput };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
|
|
3
|
+
declare const INDEX_SUFFIX = "/index";
|
|
4
|
+
declare const DEFAULT_META_FILE = "_meta.json";
|
|
5
|
+
declare const DEFAULT_PAGE_FILE = "index.mdx";
|
|
6
|
+
declare const DEFAULT_ORDER = 999;
|
|
7
|
+
|
|
8
|
+
/** Index page associated with a directory node. */
|
|
9
|
+
interface ContentTreeIndexNode {
|
|
10
|
+
type: "page";
|
|
11
|
+
name: string;
|
|
12
|
+
url: string;
|
|
13
|
+
id: string;
|
|
14
|
+
}
|
|
15
|
+
/** A page node in the content tree. */
|
|
16
|
+
interface ContentTreePageNode {
|
|
17
|
+
type: "page";
|
|
18
|
+
name: string;
|
|
19
|
+
id: string;
|
|
20
|
+
url: string;
|
|
21
|
+
order: number;
|
|
22
|
+
}
|
|
23
|
+
/** A directory node in the content tree. */
|
|
24
|
+
interface ContentTreeDirectoryNode {
|
|
25
|
+
type: "directory";
|
|
26
|
+
name: string;
|
|
27
|
+
id: string;
|
|
28
|
+
children: ContentTreeNode[];
|
|
29
|
+
index?: ContentTreeIndexNode;
|
|
30
|
+
order: number;
|
|
31
|
+
}
|
|
32
|
+
/** A node in the content tree — either a page or a directory. */
|
|
33
|
+
type ContentTreeNode = ContentTreePageNode | ContentTreeDirectoryNode;
|
|
34
|
+
/** Recursive type that strips the `order` field from a tree node and its descendants. */
|
|
35
|
+
type WithoutOrder = {
|
|
36
|
+
type: "page";
|
|
37
|
+
name: string;
|
|
38
|
+
id: string;
|
|
39
|
+
url: string;
|
|
40
|
+
} | {
|
|
41
|
+
type: "directory";
|
|
42
|
+
name: string;
|
|
43
|
+
id: string;
|
|
44
|
+
children: WithoutOrder[];
|
|
45
|
+
index?: ContentTreeIndexNode;
|
|
46
|
+
};
|
|
47
|
+
/** Minimal frontmatter fields used by the core scanning logic. */
|
|
48
|
+
interface BaseFrontmatter {
|
|
49
|
+
title: string;
|
|
50
|
+
description?: string;
|
|
51
|
+
order?: number;
|
|
52
|
+
nav?: string;
|
|
53
|
+
}
|
|
54
|
+
/** What a `mapFrontmatter` callback must return. */
|
|
55
|
+
interface FrontmatterResult {
|
|
56
|
+
title: string;
|
|
57
|
+
description?: string;
|
|
58
|
+
nav?: string;
|
|
59
|
+
order?: number;
|
|
60
|
+
/** Arbitrary extra fields that flow into `ScannedPage.extra`. */
|
|
61
|
+
extra?: Record<string, unknown>;
|
|
62
|
+
}
|
|
63
|
+
/** A parsed content page with extracted metadata. */
|
|
64
|
+
interface ScannedPage {
|
|
65
|
+
key: string;
|
|
66
|
+
title: string;
|
|
67
|
+
description?: string;
|
|
68
|
+
nav?: string;
|
|
69
|
+
order: number;
|
|
70
|
+
file: string;
|
|
71
|
+
segments: string[];
|
|
72
|
+
extra?: Record<string, unknown>;
|
|
73
|
+
}
|
|
74
|
+
/** Metadata read from a directory's `_meta.json` file. */
|
|
75
|
+
interface DirectoryMeta {
|
|
76
|
+
name?: string;
|
|
77
|
+
order?: number;
|
|
78
|
+
/** Arbitrary extra fields from the metadata file that aren't part of the base schema. */
|
|
79
|
+
extra?: Record<string, unknown>;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Resolves the display label for a directory node in the content tree.
|
|
83
|
+
*
|
|
84
|
+
* @param dirName - The raw directory name (slug)
|
|
85
|
+
* @param meta - Parsed metadata from the directory's `_meta.json` file
|
|
86
|
+
* @param indexPage - The index page for this directory, if one exists
|
|
87
|
+
* @param acronyms - Set of words to fully uppercase when humanizing
|
|
88
|
+
* @returns The display label for the directory node
|
|
89
|
+
*/
|
|
90
|
+
type DirectoryLabelResolver = (dirName: string, meta: DirectoryMeta, indexPage: ScannedPage | undefined, acronyms: Set<string>) => string;
|
|
91
|
+
/**
|
|
92
|
+
* Maps raw frontmatter data to the fields used by the content tree.
|
|
93
|
+
*
|
|
94
|
+
* @param raw - The parsed frontmatter object from gray-matter
|
|
95
|
+
* @param file - The relative file path (for error messages or conditional logic)
|
|
96
|
+
* @returns The extracted frontmatter fields
|
|
97
|
+
*/
|
|
98
|
+
type FrontmatterMapper = (raw: Record<string, unknown>, file: string) => FrontmatterResult;
|
|
99
|
+
/**
|
|
100
|
+
* Post-processes scanned pages before tree building.
|
|
101
|
+
* Use this to enrich pages with computed fields (e.g., resolving module names from ancestors).
|
|
102
|
+
*/
|
|
103
|
+
type PageEnricher = (pages: ScannedPage[], pageByKey: Map<string, ScannedPage>) => void;
|
|
104
|
+
/**
|
|
105
|
+
* Maps a scanned page to the object shape written to the generated output file.
|
|
106
|
+
* The returned object is serialized as a value in the `pages` Map.
|
|
107
|
+
*/
|
|
108
|
+
type PageEntryMapper = (page: ScannedPage) => Record<string, unknown>;
|
|
109
|
+
/** Configuration for the content tree generator. */
|
|
110
|
+
interface ContentTreeGeneratorOptions {
|
|
111
|
+
/** Path to the content directory to scan. */
|
|
112
|
+
docsDir: string;
|
|
113
|
+
/** Path where the generated TypeScript file is written. */
|
|
114
|
+
outFile: string;
|
|
115
|
+
/** URL prefix prepended to page paths (e.g., `"/docs"`). */
|
|
116
|
+
urlPrefix: string;
|
|
117
|
+
/** Display name for the root tree object (e.g., `"Docs"`). */
|
|
118
|
+
treeName: string;
|
|
119
|
+
/** If provided, wraps top-level children in a synthetic root directory node. */
|
|
120
|
+
root?: {
|
|
121
|
+
name: string;
|
|
122
|
+
id: string;
|
|
123
|
+
};
|
|
124
|
+
/** Type to import in the generated file for the tree variable. */
|
|
125
|
+
treeType?: {
|
|
126
|
+
from: string;
|
|
127
|
+
name: string;
|
|
128
|
+
};
|
|
129
|
+
/** Type to import in the generated file for the pages Map values. */
|
|
130
|
+
pageType?: {
|
|
131
|
+
from: string;
|
|
132
|
+
name: string;
|
|
133
|
+
};
|
|
134
|
+
/** Export name for the pages Map. @default "pages" */
|
|
135
|
+
pagesExportName?: string;
|
|
136
|
+
/** Export name for the tree object. @default "docsTree" */
|
|
137
|
+
treeExportName?: string;
|
|
138
|
+
/** Acronyms to uppercase when humanizing directory names. */
|
|
139
|
+
acronyms?: string[] | Set<string>;
|
|
140
|
+
/** Filename for directory metadata. @default "_meta.json" */
|
|
141
|
+
metaFile?: string;
|
|
142
|
+
/** Filename to match as a page entry. @default "index.mdx" */
|
|
143
|
+
pageFile?: string;
|
|
144
|
+
/** Custom frontmatter mapper. The default handles `BaseFrontmatter` fields plus `module` in `extra`. */
|
|
145
|
+
mapFrontmatter?: FrontmatterMapper;
|
|
146
|
+
/**
|
|
147
|
+
* Post-processes pages after scanning.
|
|
148
|
+
* @default no-op — pass `resolveModules` to enable module resolution from ancestors.
|
|
149
|
+
*/
|
|
150
|
+
enrichPages?: PageEnricher;
|
|
151
|
+
/** Customizes the per-page entry shape in the generated output. */
|
|
152
|
+
mapPageEntry?: PageEntryMapper;
|
|
153
|
+
/**
|
|
154
|
+
* Resolves the display label for directory nodes.
|
|
155
|
+
* @default Falls back to `extra.module` → `meta.name` → `humanize(dirName)`.
|
|
156
|
+
*/
|
|
157
|
+
resolveDirectoryLabel?: DirectoryLabelResolver;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
interface GenerateDataResult {
|
|
161
|
+
pages: ScannedPage[];
|
|
162
|
+
tree: WithoutOrder;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Runs the full scan → enrich → build pipeline and returns the raw data
|
|
166
|
+
* without writing any files.
|
|
167
|
+
*
|
|
168
|
+
* @param opts - Generator configuration
|
|
169
|
+
* @returns The scanned pages and the built tree (with order fields stripped)
|
|
170
|
+
*/
|
|
171
|
+
declare function generateData(opts: ContentTreeGeneratorOptions): Promise<GenerateDataResult>;
|
|
172
|
+
/**
|
|
173
|
+
* Writes the generated data to a TypeScript file using the configured template.
|
|
174
|
+
*
|
|
175
|
+
* @param opts - Generator configuration (controls export names, type imports, page entry shape)
|
|
176
|
+
* @param data - The data to serialize (from `generateData`)
|
|
177
|
+
*/
|
|
178
|
+
declare function writeOutput(opts: ContentTreeGeneratorOptions, data: GenerateDataResult): Promise<void>;
|
|
179
|
+
/**
|
|
180
|
+
* Generates the content tree data and writes it to the configured output file.
|
|
181
|
+
*
|
|
182
|
+
* @param opts - Generator configuration
|
|
183
|
+
*/
|
|
184
|
+
declare function generate(opts: ContentTreeGeneratorOptions): Promise<void>;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Vite plugin that scans a content directory, extracts frontmatter,
|
|
188
|
+
* and generates a typed navigation tree + page index as a TypeScript file.
|
|
189
|
+
*
|
|
190
|
+
* Runs at build start and watches for changes during dev.
|
|
191
|
+
*
|
|
192
|
+
* @param opts - Generator configuration
|
|
193
|
+
* @returns A Vite plugin
|
|
194
|
+
*/
|
|
195
|
+
declare function contentTreeGeneratorPlugin(opts: ContentTreeGeneratorOptions): Plugin;
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Default frontmatter mapper that extracts base fields and passes
|
|
199
|
+
* all remaining fields through as `extra`.
|
|
200
|
+
*/
|
|
201
|
+
declare const defaultMapFrontmatter: FrontmatterMapper;
|
|
202
|
+
/**
|
|
203
|
+
* Reads and parses a directory metadata file (e.g., `_meta.json`).
|
|
204
|
+
*
|
|
205
|
+
* @param docsDir - Root content directory path
|
|
206
|
+
* @param dirPath - Relative path to the directory within docsDir
|
|
207
|
+
* @param metaFile - Name of the metadata file to look for
|
|
208
|
+
* @returns Parsed metadata or an empty object if the file doesn't exist
|
|
209
|
+
*/
|
|
210
|
+
declare function readDirectoryMeta(docsDir: string, dirPath: string, metaFile: string): Promise<DirectoryMeta>;
|
|
211
|
+
/**
|
|
212
|
+
* Recursively scans a content directory for page files, extracts frontmatter,
|
|
213
|
+
* and returns an array of scanned pages.
|
|
214
|
+
*
|
|
215
|
+
* @param docsDir - Root content directory to scan
|
|
216
|
+
* @param pageFile - Filename to match as a page entry (e.g., `"index.mdx"`)
|
|
217
|
+
* @param mapFrontmatter - Callback to extract fields from raw frontmatter data
|
|
218
|
+
* @returns Array of scanned pages with extracted metadata
|
|
219
|
+
*/
|
|
220
|
+
declare function scanPages(docsDir: string, pageFile: string, mapFrontmatter?: FrontmatterMapper): Promise<ScannedPage[]>;
|
|
221
|
+
/**
|
|
222
|
+
* Resolves the `extra.module` field for each page by looking up its module-root ancestor.
|
|
223
|
+
* Pages inherit the module from the root page of their first path segment.
|
|
224
|
+
*
|
|
225
|
+
* This is the default `enrichPages` implementation.
|
|
226
|
+
*/
|
|
227
|
+
declare function resolveModules(pages: ScannedPage[], pageByKey: Map<string, ScannedPage>): void;
|
|
228
|
+
|
|
229
|
+
/** Pre-computed index that groups pages by parent path for O(1) lookups during tree building. */
|
|
230
|
+
interface PageIndex {
|
|
231
|
+
directChildren: Map<string, ScannedPage[]>;
|
|
232
|
+
subDirNames: Map<string, Set<string>>;
|
|
233
|
+
}
|
|
234
|
+
/** Context threaded through recursive `buildChildren` calls. */
|
|
235
|
+
interface BuildContext {
|
|
236
|
+
pageIndex: PageIndex;
|
|
237
|
+
metas: Map<string, DirectoryMeta>;
|
|
238
|
+
urlPrefix: string;
|
|
239
|
+
acronyms: Set<string>;
|
|
240
|
+
resolveDirectoryLabel: DirectoryLabelResolver;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Pre-groups pages into a lookup index so `buildChildren` can avoid
|
|
244
|
+
* re-filtering the full page list at every recursion level.
|
|
245
|
+
*
|
|
246
|
+
* @param pages - All scanned pages (root page with key="" is excluded from grouping)
|
|
247
|
+
* @returns A `PageIndex` with O(1) lookups by parent path
|
|
248
|
+
*/
|
|
249
|
+
declare function buildPageIndex(pages: ScannedPage[]): PageIndex;
|
|
250
|
+
/**
|
|
251
|
+
* Converts a kebab-case slug to Title Case, uppercasing known acronyms.
|
|
252
|
+
*
|
|
253
|
+
* @param slug - The slug to humanize (e.g., `"ses-api-reference"`)
|
|
254
|
+
* @param acronyms - Set of words to fully uppercase (e.g., `"ses"` → `"SES"`)
|
|
255
|
+
* @returns The humanized string (e.g., `"SES API Reference"`)
|
|
256
|
+
*/
|
|
257
|
+
declare function humanize(slug: string, acronyms: Set<string>): string;
|
|
258
|
+
/**
|
|
259
|
+
* Default directory label resolver.
|
|
260
|
+
* Falls back through: `extra.module` → `meta.name` → `humanize(dirName)`.
|
|
261
|
+
*/
|
|
262
|
+
declare const defaultResolveDirectoryLabel: DirectoryLabelResolver;
|
|
263
|
+
/**
|
|
264
|
+
* Recursively builds a sorted array of child nodes for a given parent path.
|
|
265
|
+
*
|
|
266
|
+
* @param parentPath - The key prefix for the parent (empty string for root)
|
|
267
|
+
* @param ctx - Build context with shared configuration and pre-scanned metadata
|
|
268
|
+
* @returns Sorted array of tree nodes
|
|
269
|
+
*/
|
|
270
|
+
declare function buildChildren(parentPath: string, ctx: BuildContext): ContentTreeNode[];
|
|
271
|
+
/**
|
|
272
|
+
* Recursively removes the `order` field from a tree node and all its descendants.
|
|
273
|
+
* The `order` field is only used for sorting and is not needed in the final output.
|
|
274
|
+
*/
|
|
275
|
+
declare function stripOrder(node: ContentTreeNode): WithoutOrder;
|
|
276
|
+
|
|
277
|
+
export { type BaseFrontmatter, type BuildContext, type ContentTreeDirectoryNode, type ContentTreeGeneratorOptions, type ContentTreeIndexNode, type ContentTreeNode, type ContentTreePageNode, DEFAULT_META_FILE, DEFAULT_ORDER, DEFAULT_PAGE_FILE, type DirectoryLabelResolver, type DirectoryMeta, type FrontmatterMapper, type FrontmatterResult, type GenerateDataResult, INDEX_SUFFIX, type PageEnricher, type PageEntryMapper, type PageIndex, type ScannedPage, type WithoutOrder, buildChildren, buildPageIndex, contentTreeGeneratorPlugin, defaultMapFrontmatter, defaultResolveDirectoryLabel, generate, generateData, humanize, readDirectoryMeta, resolveModules, scanPages, stripOrder, writeOutput };
|