docula 0.41.1 → 0.90.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 (56) hide show
  1. package/README.md +228 -4
  2. package/dist/docula.d.ts +240 -16
  3. package/dist/docula.js +1596 -222
  4. package/package.json +11 -9
  5. package/templates/classic/api.hbs +214 -0
  6. package/{template → templates/classic}/changelog-entry.hbs +2 -0
  7. package/{template → templates/classic}/changelog.hbs +2 -0
  8. package/templates/classic/css/api.css +753 -0
  9. package/{template → templates/classic}/css/base.css +10 -0
  10. package/{template → templates/classic}/css/multipage.css +7 -0
  11. package/{template → templates/classic}/docs.hbs +3 -1
  12. package/{template/index.hbs → templates/classic/home.hbs} +9 -1
  13. package/templates/classic/includes/api-try-it.hbs +61 -0
  14. package/templates/classic/includes/multipage/api-reference.hbs +1 -0
  15. package/templates/classic/includes/multipage/documentation.hbs +1 -0
  16. package/{template → templates/classic}/includes/multipage/hero.hbs +1 -2
  17. package/{template → templates/classic}/includes/multipage/home.hbs +3 -3
  18. package/{template → templates/classic}/includes/singlepage/content.hbs +3 -3
  19. package/templates/classic/js/api.js +282 -0
  20. package/templates/modern/api.hbs +215 -0
  21. package/templates/modern/changelog-entry.hbs +36 -0
  22. package/templates/modern/changelog.hbs +38 -0
  23. package/templates/modern/css/api.css +1051 -0
  24. package/templates/modern/css/highlight/highlight.min.js +1433 -0
  25. package/templates/modern/css/highlight/styles/base16/docula.css +123 -0
  26. package/templates/modern/css/home.css +96 -0
  27. package/templates/modern/css/styles.css +711 -0
  28. package/templates/modern/docs.hbs +30 -0
  29. package/templates/modern/home.hbs +53 -0
  30. package/templates/modern/includes/api-reference.hbs +1 -0
  31. package/templates/modern/includes/api-try-it.hbs +61 -0
  32. package/templates/modern/includes/doc.hbs +18 -0
  33. package/templates/modern/includes/documentation.hbs +1 -0
  34. package/templates/modern/includes/footer.hbs +6 -0
  35. package/templates/modern/includes/header-bar.hbs +57 -0
  36. package/templates/modern/includes/header.hbs +15 -0
  37. package/templates/modern/includes/hero.hbs +11 -0
  38. package/templates/modern/includes/home.hbs +46 -0
  39. package/templates/modern/includes/scripts.hbs +164 -0
  40. package/templates/modern/includes/sidebar.hbs +22 -0
  41. package/templates/modern/includes/theme-toggle.hbs +5 -0
  42. package/templates/modern/js/api.js +300 -0
  43. package/template/api.hbs +0 -28
  44. package/template/releases.hbs +0 -86
  45. /package/{template → templates/classic}/css/highlight/highlight.min.js +0 -0
  46. /package/{template → templates/classic}/css/highlight/styles/base16/dracula.min.css +0 -0
  47. /package/{template → templates/classic}/css/landing.css +0 -0
  48. /package/{template → templates/classic}/css/singlepage.css +0 -0
  49. /package/{template → templates/classic}/includes/footer.hbs +0 -0
  50. /package/{template → templates/classic}/includes/header.hbs +0 -0
  51. /package/{template → templates/classic}/includes/multipage/doc.hbs +0 -0
  52. /package/{template → templates/classic}/includes/multipage/header.hbs +0 -0
  53. /package/{template → templates/classic}/includes/multipage/scripts.hbs +0 -0
  54. /package/{template → templates/classic}/includes/multipage/sidebar.hbs +0 -0
  55. /package/{template → templates/classic}/includes/scripts.hbs +0 -0
  56. /package/{template → templates/classic}/includes/singlepage/hero.hbs +0 -0
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  [![tests](https://github.com/jaredwray/docula/actions/workflows/tests.yaml/badge.svg)](https://github.com/jaredwray/docula/actions/workflows/tests.yaml)
6
6
  [![GitHub license](https://img.shields.io/github/license/jaredwray/docula)](https://github.com/jaredwray/docula/blob/master/LICENSE)
7
- [![codecov](https://codecov.io/gh/jaredwray/docula/graph/badge.svg?token=RS0GPY4V4M)](https://codecov.io/gh/jaredwray/docula)
7
+ [![codecov](https://codecov.io/gh/jaredwray/docula/branch/main/graph/badge.svg?token=RS0GPY4V4M)](https://codecov.io/gh/jaredwray/docula)
8
8
  [![npm](https://img.shields.io/npm/dm/docula)](https://npmjs.com/package/docula)
9
9
  [![npm](https://img.shields.io/npm/v/docula)](https://npmjs.com/package/docula)
10
10
 
@@ -12,10 +12,15 @@
12
12
  - [Features](#features)
13
13
  - [Open Source Examples](#open-source-examples)
14
14
  - [Getting Started](#getting-started)
15
+ - [Serve your site locally](#serve-your-site-locally)
15
16
  - [TypeScript Configuration](#typescript-configuration)
17
+ - [Theme Mode](#theme-mode)
16
18
  - [Using Your own Template](#using-your-own-template)
17
19
  - [Building Multiple Pages](#building-multiple-pages)
20
+ - [Including Assets in Markdown](#including-assets-in-markdown)
18
21
  - [Public Folder](#public-folder)
22
+ - [API Reference](#api-reference)
23
+ - [LLM Files](#llm-files)
19
24
  - [Announcements](#announcements)
20
25
  - [Changelog](#changelog)
21
26
  - [Alert, Info, Warn Styling](#alert-info-warn-styling)
@@ -32,6 +37,7 @@
32
37
  * Full TypeScript support with typed configuration and IDE autocompletion.
33
38
  * Support for single page with readme or multiple markdown pages in a docs folder.
34
39
  * Will generate a sitemap.xml and robots.txt for your site.
40
+ * Automatically generates `llms.txt` and `llms-full.txt` for LLM-friendly indexing of docs, API reference, and changelog content.
35
41
  * Uses Github release notes to generate a changelog / releases page.
36
42
  * Uses Github to show contributors and link to their profiles.
37
43
  * Simple search is provided by default out of the box.
@@ -73,6 +79,38 @@ Simply replace the logo, favicon, and css file with your own. The readme is your
73
79
 
74
80
  This will build your site and place it in the `dist` folder. You can then host it anywhere you like.
75
81
 
82
+ ## Serve your site locally
83
+
84
+ > npx docula serve
85
+
86
+ This will build and serve your site locally at `http://localhost:3000`. You can specify a custom port with the `-p` or `--port` flag:
87
+
88
+ > npx docula serve -p 8080
89
+
90
+ ### CLI Options for serve
91
+
92
+ | Flag | Description | Default |
93
+ |------|-------------|---------|
94
+ | `-p, --port` | Set the port number | `3000` |
95
+ | `-s, --site` | Set the path where site files are located | `./site` |
96
+ | `-o, --output` | Set the output directory | `./site/dist` |
97
+ | `-w, --watch` | Watch for changes and rebuild | `false` |
98
+ | `-c, --clean` | Clean the output directory before building | `false` |
99
+
100
+ ### Watch Mode
101
+
102
+ Use the `--watch` flag to automatically rebuild your site when files change:
103
+
104
+ > npx docula serve --watch
105
+
106
+ When watch mode is enabled:
107
+ 1. An initial build runs at startup
108
+ 2. The dev server starts and serves your site
109
+ 3. File changes in `sitePath` (e.g., `./site`) are detected and trigger an automatic rebuild
110
+ 4. Changes in the output directory are ignored to prevent rebuild loops
111
+
112
+ This is useful during development when you want to see changes reflected immediately without manually re-running the build.
113
+
76
114
  # TypeScript Configuration
77
115
 
78
116
  Docula supports TypeScript configuration files (`docula.config.ts`) in addition to JavaScript (`docula.config.mjs`). TypeScript configs provide type safety and better IDE support.
@@ -92,7 +130,7 @@ import type { DoculaOptions } from 'docula';
92
130
 
93
131
  export const options: Partial<DoculaOptions> = {
94
132
  templatePath: './template',
95
- outputPath: './dist',
133
+ output: './dist',
96
134
  sitePath: './site',
97
135
  githubPath: 'your-username/your-repo',
98
136
  siteTitle: 'My Project',
@@ -130,15 +168,34 @@ When both config files exist, Docula loads them in this order (first found wins)
130
168
  | Option | Type | Default | Description |
131
169
  |--------|------|---------|-------------|
132
170
  | `templatePath` | `string` | `'./template'` | Path to custom template directory |
133
- | `outputPath` | `string` | `'./dist'` | Output directory for built site |
171
+ | `output` | `string` | `'./dist'` | Output directory for built site |
134
172
  | `sitePath` | `string` | `'./site'` | Directory containing site content |
135
173
  | `githubPath` | `string` | - | GitHub repository path (e.g., `'user/repo'`) |
136
174
  | `siteTitle` | `string` | `'docula'` | Website title |
137
175
  | `siteDescription` | `string` | - | Website description |
138
176
  | `siteUrl` | `string` | - | Website URL |
139
177
  | `port` | `number` | `3000` | Port for local development server |
140
- | `singlePage` | `boolean` | `true` | Single page or multi-page site |
178
+ | `homePage` | `boolean` | `true` | When `false`, Docula uses the first docs page as `/index.html` instead of rendering `home.hbs` |
141
179
  | `sections` | `DoculaSection[]` | - | Documentation sections |
180
+ | `openApiUrl` | `string` | - | OpenAPI spec URL for API documentation (auto-detected if `api/swagger.json` exists) |
181
+ | `enableReleaseChangelog` | `boolean` | `true` | Convert GitHub releases to changelog entries |
182
+ | `enableLlmsTxt` | `boolean` | `true` | Generate `llms.txt` and `llms-full.txt` in the build output |
183
+ | `themeMode` | `'light'` \| `'dark'` | - | Override the default theme. By default the site follows the system preference. Set to `'light'` or `'dark'` to use that theme when no user preference is stored. |
184
+ | `allowedAssets` | `string[]` | *(see [Including Assets in Markdown](#including-images-and-assets-in-markdown))* | File extensions to copy from `docs/` and `changelog/` to output |
185
+
186
+ ## Theme Mode
187
+
188
+ By default, the site follows the user's system color scheme preference. The theme toggle cycles through three modes: **system** (follows OS preference), **light**, and **dark**. The user's choice is persisted in `localStorage`.
189
+
190
+ To set the initial theme mode, use `themeMode`:
191
+
192
+ ```js
193
+ export const options = {
194
+ themeMode: 'dark',
195
+ };
196
+ ```
197
+
198
+ When `themeMode` is set, new visitors see the specified theme instead of the system preference. Once a user clicks the theme toggle, their choice takes priority and is remembered across visits.
142
199
 
143
200
  # Using Your own Template
144
201
 
@@ -172,6 +229,78 @@ title: Getting Started
172
229
  order: 2
173
230
  ```
174
231
 
232
+ If you want your docs to be the root home page (`/`) instead of rendering the template home page, set `homePage: false`:
233
+
234
+ ```js
235
+ export const options = {
236
+ homePage: false,
237
+ };
238
+ ```
239
+
240
+ # Including Assets in Markdown
241
+
242
+ Non-markdown files placed inside the `docs/` or `changelog/` directories are automatically copied to the build output, preserving their relative paths. This lets you keep images and other assets alongside the markdown that references them.
243
+
244
+ For `docs/`, only assets that are actually referenced in a document's markdown content are copied. If a file exists in the `docs/` directory but is not referenced by any document, it will not be included in the build output. For `changelog/`, all assets are copied regardless of whether they are referenced.
245
+
246
+ ```
247
+ site
248
+ ├───docs
249
+ │ ├───getting-started.md
250
+ │ ├───images
251
+ │ │ ├───architecture.png
252
+ │ │ └───screenshot.jpg
253
+ │ └───assets
254
+ │ └───example.pdf
255
+ ├───changelog
256
+ │ ├───2025-01-15-initial-release.md
257
+ │ └───images
258
+ │ └───release-banner.png
259
+ ```
260
+
261
+ After building, these files appear at the same relative paths under `dist/`:
262
+
263
+ ```
264
+ dist
265
+ ├───docs
266
+ │ ├───getting-started
267
+ │ │ └───index.html
268
+ │ ├───images
269
+ │ │ ├───architecture.png
270
+ │ │ └───screenshot.jpg
271
+ │ └───assets
272
+ │ └───example.pdf
273
+ ├───changelog
274
+ │ ├───initial-release
275
+ │ │ └───index.html
276
+ │ └───images
277
+ │ └───release-banner.png
278
+ ```
279
+
280
+ Reference assets from your markdown using relative paths:
281
+
282
+ ```md
283
+ ![Architecture](images/architecture.png)
284
+ [Download PDF](assets/example.pdf)
285
+ ```
286
+
287
+ ## Supported Extensions
288
+
289
+ By default the following file extensions are copied:
290
+
291
+ **Images:** `.png`, `.jpg`, `.jpeg`, `.gif`, `.svg`, `.webp`, `.avif`, `.ico`
292
+ **Documents:** `.pdf`, `.zip`, `.tar`, `.gz`
293
+ **Media:** `.mp4`, `.webm`, `.ogg`, `.mp3`, `.wav`
294
+ **Data:** `.json`, `.xml`, `.csv`, `.txt`
295
+
296
+ Files with extensions not in this list are ignored. To customize the list, set `allowedAssets` in your config:
297
+
298
+ ```js
299
+ export const options = {
300
+ allowedAssets: ['.png', '.jpg', '.gif', '.svg', '.pdf', '.custom'],
301
+ };
302
+ ```
303
+
175
304
  # Public Folder
176
305
 
177
306
  If you have static assets like images, fonts, or other files that need to be copied directly to your built site, you can use a `public` folder. Any files placed in the `public` folder within your site directory will be automatically copied to the root of your `dist` output folder during the build process.
@@ -228,6 +357,101 @@ This is useful for:
228
357
  - Custom fonts
229
358
  - Any other static assets that need to be served from your site
230
359
 
360
+ # API Reference
361
+
362
+ Docula can generate an API Reference page from an OpenAPI (Swagger) specification. The spec is parsed at build time and rendered as a native, interactive API reference (inspired by [Scalar](https://github.com/scalar/scalar)) with grouped endpoints, method badges, schema tables, code examples, and search — all with no external dependencies. The page is available at `/api`.
363
+
364
+ ## Auto-Detection
365
+
366
+ If your site directory contains an `api/swagger.json` file, Docula will automatically detect it and generate the API Reference page — no configuration needed:
367
+
368
+ ```
369
+ site
370
+ ├───api
371
+ │ └───swagger.json
372
+ ├───docs
373
+ ├───logo.svg
374
+ ├───favicon.ico
375
+ └───docula.config.mjs
376
+ ```
377
+
378
+ ## Explicit Configuration
379
+
380
+ You can also set the `openApiUrl` option in your config to point to any OpenAPI spec, either a local path or a remote URL:
381
+
382
+ ```js
383
+ export const options = {
384
+ openApiUrl: '/api/swagger.json',
385
+ // or a remote URL:
386
+ // openApiUrl: 'https://petstore.swagger.io/v2/swagger.json',
387
+ };
388
+ ```
389
+
390
+ When `openApiUrl` is set explicitly, it takes priority over auto-detection.
391
+
392
+ ## Spec Requirements
393
+
394
+ The file must be a valid OpenAPI 3.x or Swagger 2.0 JSON specification. A minimal example:
395
+
396
+ ```json
397
+ {
398
+ "openapi": "3.0.0",
399
+ "info": {
400
+ "title": "My API",
401
+ "version": "1.0.0"
402
+ },
403
+ "paths": {}
404
+ }
405
+ ```
406
+
407
+ # LLM Files
408
+
409
+ Docula generates two LLM-focused files in the output directory by default:
410
+
411
+ - `/llms.txt` - a compact index of your docs, API reference, and changelog URLs.
412
+ - `/llms-full.txt` - expanded content including markdown bodies for docs/changelog and local OpenAPI spec text.
413
+
414
+ ## What Gets Included
415
+
416
+ `/llms.txt` includes:
417
+ - Site title and description
418
+ - A link to `/llms-full.txt`
419
+ - Documentation links (absolute URLs)
420
+ - API Reference link when API docs are generated
421
+ - Changelog landing page and the latest 20 changelog entries
422
+
423
+ `/llms-full.txt` includes:
424
+ - Site title and description
425
+ - Full markdown body for each docs page
426
+ - Full markdown body for each changelog entry
427
+ - Full local OpenAPI spec text when available (for example `site/api/swagger.json`)
428
+
429
+ If `openApiUrl` points to a remote URL, `/llms-full.txt` includes only the URL reference instead of fetching content over the network.
430
+
431
+ ## Configuration
432
+
433
+ To disable generation:
434
+
435
+ ```js
436
+ export const options = {
437
+ enableLlmsTxt: false,
438
+ };
439
+ ```
440
+
441
+ ## Custom Overrides
442
+
443
+ You can override generated output by providing custom files in your site directory:
444
+
445
+ - `site/llms.txt`
446
+ - `site/llms-full.txt`
447
+
448
+ If present, Docula copies these files to output as-is.
449
+
450
+ ## Notes
451
+
452
+ - These files are generated in the output root (`dist/llms.txt` and `dist/llms-full.txt`).
453
+ - They are not added to `sitemap.xml`.
454
+
231
455
  # Announcements
232
456
 
233
457
  You can display an announcement banner on your home page by creating an `announcement.md` file in your site directory. This is useful for highlighting important updates, new releases, or any time-sensitive information.
package/dist/docula.d.ts CHANGED
@@ -1,22 +1,88 @@
1
+ import fs from 'node:fs';
1
2
  import http from 'node:http';
2
3
  export { Writr } from 'writr';
3
4
 
4
- type DoculaSection = {
5
+ type ApiSchemaProperty = {
5
6
  name: string;
6
- order?: number;
7
+ type: string;
8
+ required: boolean;
9
+ description: string;
10
+ enumValues?: string[];
11
+ };
12
+ type ApiOperationParameter = {
13
+ name: string;
14
+ in: string;
15
+ required: boolean;
16
+ type: string;
17
+ description: string;
18
+ };
19
+ type ApiRequestBody = {
20
+ contentType: string;
21
+ schemaProperties: ApiSchemaProperty[];
22
+ example: string;
23
+ };
24
+ type ApiResponse = {
25
+ statusCode: string;
26
+ statusClass: string;
27
+ description: string;
28
+ contentType: string;
29
+ schemaProperties: ApiSchemaProperty[];
30
+ example: string;
31
+ };
32
+ type ApiCodeExamples = {
33
+ curl: string;
34
+ javascript: string;
35
+ python: string;
36
+ };
37
+ type ApiOperation = {
38
+ id: string;
39
+ method: string;
40
+ methodUpper: string;
7
41
  path: string;
8
- children?: DoculaSection[];
42
+ summary: string;
43
+ description: string;
44
+ parameters: ApiOperationParameter[];
45
+ requestBody?: ApiRequestBody;
46
+ responses: ApiResponse[];
47
+ codeExamples: ApiCodeExamples;
48
+ };
49
+ type ApiGroup = {
50
+ name: string;
51
+ description: string;
52
+ id: string;
53
+ operations: ApiOperation[];
54
+ };
55
+ type ApiSpecData = {
56
+ info: {
57
+ title: string;
58
+ description: string;
59
+ version: string;
60
+ };
61
+ servers: Array<{
62
+ url: string;
63
+ description: string;
64
+ }>;
65
+ groups: ApiGroup[];
66
+ };
67
+
68
+ type GithubData = {
69
+ releases: Record<string, unknown>;
70
+ contributors: Record<string, unknown>;
9
71
  };
10
72
 
11
73
  declare class DoculaOptions {
12
74
  /**
13
- * Path to the template directory
75
+ * Name of the built-in template to use (e.g., "modern", "classic")
76
+ */
77
+ template: string;
78
+ /**
79
+ * Path to the template directory. When set, overrides the `template` option.
14
80
  */
15
81
  templatePath: string;
16
82
  /**
17
83
  * Path to the output directory
18
84
  */
19
- outputPath: string;
85
+ output: string;
20
86
  /**
21
87
  * Path to the site directory
22
88
  */
@@ -41,10 +107,6 @@ declare class DoculaOptions {
41
107
  * Port to run the server
42
108
  */
43
109
  port: number;
44
- /**
45
- * Single page website
46
- */
47
- singlePage: boolean;
48
110
  /**
49
111
  * Sections
50
112
  */
@@ -55,15 +117,164 @@ declare class DoculaOptions {
55
117
  * Supports both external URLs (https://...) and relative paths (/openapi.json)
56
118
  */
57
119
  openApiUrl?: string;
120
+ /**
121
+ * When true, GitHub releases are converted to changelog entries and merged
122
+ * with file-based changelog entries. Requires a changelog template to exist.
123
+ */
124
+ enableReleaseChangelog: boolean;
125
+ /**
126
+ * When false, the first document becomes the home page (index.html)
127
+ * and the home.hbs template is not rendered.
128
+ */
129
+ homePage: boolean;
130
+ /**
131
+ * When true, generates llms.txt and llms-full.txt files for the built site.
132
+ */
133
+ enableLlmsTxt: boolean;
134
+ /**
135
+ * Override the default theme toggle. By default the site follows the system
136
+ * preference. Set to "light" or "dark" to use that theme when no user
137
+ * preference is stored in localStorage.
138
+ */
139
+ themeMode?: "light" | "dark";
140
+ /**
141
+ * When true, automatically adds generated paths (e.g., .cache) to the
142
+ * site directory's .gitignore file if not already present.
143
+ */
144
+ autoUpdateIgnores: boolean;
145
+ /**
146
+ * File extensions to copy as assets from docs/ and changelog/ directories.
147
+ * Override in docula.config to customize.
148
+ */
149
+ allowedAssets: string[];
58
150
  constructor(options?: Record<string, unknown>);
59
151
  parseOptions(options: Record<string, any>): void;
60
152
  }
61
153
 
154
+ type DoculaChangelogEntry = {
155
+ title: string;
156
+ date: string;
157
+ formattedDate: string;
158
+ tag?: string;
159
+ tagClass?: string;
160
+ slug: string;
161
+ content: string;
162
+ generatedHtml: string;
163
+ urlPath: string;
164
+ };
165
+ type DoculaData = {
166
+ siteUrl: string;
167
+ siteTitle: string;
168
+ siteDescription: string;
169
+ sitePath: string;
170
+ templatePath: string;
171
+ output: string;
172
+ githubPath?: string;
173
+ github?: GithubData;
174
+ templates?: DoculaTemplates;
175
+ hasDocuments?: boolean;
176
+ hasChangelog?: boolean;
177
+ sections?: DoculaSection[];
178
+ documents?: DoculaDocument[];
179
+ sidebarItems?: DoculaSection[];
180
+ announcement?: string;
181
+ openApiUrl?: string;
182
+ hasApi?: boolean;
183
+ apiSpec?: ApiSpecData;
184
+ changelogEntries?: DoculaChangelogEntry[];
185
+ homePage?: boolean;
186
+ themeMode?: string;
187
+ };
188
+ type DoculaTemplates = {
189
+ home: string;
190
+ docPage?: string;
191
+ api?: string;
192
+ changelog?: string;
193
+ changelogEntry?: string;
194
+ };
195
+ type DoculaSection = {
196
+ name: string;
197
+ order?: number;
198
+ path: string;
199
+ children?: DoculaSection[];
200
+ };
201
+ type DoculaDocument = {
202
+ title: string;
203
+ navTitle: string;
204
+ description: string;
205
+ order?: number;
206
+ section?: string;
207
+ keywords: string[];
208
+ content: string;
209
+ markdown: string;
210
+ generatedHtml: string;
211
+ documentPath: string;
212
+ urlPath: string;
213
+ isRoot: boolean;
214
+ };
215
+ declare class DoculaBuilder {
216
+ private readonly _options;
217
+ private readonly _ecto;
218
+ private readonly _console;
219
+ constructor(options?: DoculaOptions, engineOptions?: any);
220
+ get options(): DoculaOptions;
221
+ build(): Promise<void>;
222
+ validateOptions(options: DoculaOptions): void;
223
+ getGithubData(githubPath: string): Promise<GithubData>;
224
+ getTemplates(templatePath: string, hasDocuments: boolean, hasChangelog?: boolean): Promise<DoculaTemplates>;
225
+ getTemplateFile(path: string, name: string): Promise<string | undefined>;
226
+ buildRobotsPage(options: DoculaOptions): Promise<void>;
227
+ buildSiteMapPage(data: DoculaData): Promise<void>;
228
+ buildLlmsFiles(data: DoculaData): Promise<void>;
229
+ private generateLlmsIndexContent;
230
+ private generateLlmsFullContent;
231
+ private buildAbsoluteSiteUrl;
232
+ private normalizePathForUrl;
233
+ private isRemoteUrl;
234
+ private resolveOpenApiSpecUrl;
235
+ private resolveLocalOpenApiPath;
236
+ private getSafeSiteOverrideFileContent;
237
+ private getSafeLocalOpenApiSpec;
238
+ private isPathWithinBasePath;
239
+ private toPosixPath;
240
+ buildIndexPage(data: DoculaData): Promise<void>;
241
+ buildDocsHomePage(data: DoculaData): Promise<void>;
242
+ buildReadmeSection(data: DoculaData): Promise<string>;
243
+ buildAnnouncementSection(data: DoculaData): Promise<string | undefined>;
244
+ buildDocsPages(data: DoculaData): Promise<void>;
245
+ buildApiPage(data: DoculaData): Promise<void>;
246
+ getChangelogEntries(changelogPath: string): DoculaChangelogEntry[];
247
+ parseChangelogEntry(filePath: string): DoculaChangelogEntry;
248
+ convertReleaseToChangelogEntry(release: Record<string, any>): DoculaChangelogEntry;
249
+ getReleasesAsChangelogEntries(releases: any[]): DoculaChangelogEntry[];
250
+ buildChangelogPage(data: DoculaData): Promise<void>;
251
+ buildChangelogEntryPages(data: DoculaData): Promise<void>;
252
+ generateSidebarItems(data: DoculaData): DoculaSection[];
253
+ getDocuments(sitePath: string, doculaData: DoculaData): DoculaDocument[];
254
+ getDocumentInDirectory(sitePath: string): DoculaDocument[];
255
+ getSections(sitePath: string, doculaOptions: DoculaOptions): DoculaSection[];
256
+ mergeSectionWithOptions(section: DoculaSection, options: DoculaOptions): DoculaSection;
257
+ parseDocumentData(documentPath: string): DoculaDocument;
258
+ private hasTableOfContents;
259
+ private directoryContainsMarkdown;
260
+ private mergeTemplateOverrides;
261
+ private ensureCacheInGitignore;
262
+ private isCacheFresh;
263
+ private listFilesRecursive;
264
+ private copyDirectory;
265
+ private copyPublicFolder;
266
+ private copyPublicDirectory;
267
+ private copyDocumentSiblingAssets;
268
+ private listContentAssets;
269
+ private copyContentAssets;
270
+ }
271
+
62
272
  declare class Docula {
63
273
  private _options;
64
274
  private readonly _console;
65
275
  private _configFileModule;
66
276
  private _server;
277
+ private _watcher;
67
278
  /**
68
279
  * Initialize the Docula class
69
280
  * @param {DoculaOptions} options
@@ -86,11 +297,23 @@ declare class Docula {
86
297
  * @returns {http.Server | undefined}
87
298
  */
88
299
  get server(): http.Server | undefined;
300
+ /**
301
+ * The file watcher used in watch mode
302
+ * @returns {fs.FSWatcher | undefined}
303
+ */
304
+ get watcher(): fs.FSWatcher | undefined;
89
305
  /**
90
306
  * The config file module. This is the module that is loaded from the docula.config.ts or docula.config.mjs file
91
307
  * @returns {any}
92
308
  */
93
309
  get configFileModule(): any;
310
+ /**
311
+ * Remove the .cache directory inside the site path.
312
+ * Resolves the path and verifies it stays within sitePath to prevent
313
+ * path-traversal attacks.
314
+ * @param {string} sitePath
315
+ */
316
+ private cleanCache;
94
317
  /**
95
318
  * Check for updates
96
319
  * @returns {void}
@@ -102,12 +325,6 @@ declare class Docula {
102
325
  * @returns {Promise<void>}
103
326
  */
104
327
  execute(process: NodeJS.Process): Promise<void>;
105
- /**
106
- * Checks if the site is a single page website
107
- * @param {string} sitePath
108
- * @returns {boolean}
109
- */
110
- isSinglePageWebsite(sitePath: string): boolean;
111
328
  /**
112
329
  * Generate the init files
113
330
  * @param {string} sitePath
@@ -127,6 +344,13 @@ declare class Docula {
127
344
  * @returns {Promise<void>}
128
345
  */
129
346
  loadConfigFile(sitePath: string): Promise<void>;
347
+ /**
348
+ * Watch the site path for file changes and rebuild on change
349
+ * @param {DoculaOptions} options
350
+ * @param {DoculaBuilder} builder
351
+ * @returns {fs.FSWatcher}
352
+ */
353
+ watch(options: DoculaOptions, builder: DoculaBuilder): fs.FSWatcher;
130
354
  /**
131
355
  * Serve the site based on the options (port and output path)
132
356
  * @param {DoculaOptions} options
@@ -135,4 +359,4 @@ declare class Docula {
135
359
  serve(options: DoculaOptions): Promise<http.Server>;
136
360
  }
137
361
 
138
- export { Docula as default };
362
+ export { DoculaOptions, Docula as default };