bun-plugin-bunpress 0.1.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.
- package/LICENSE.md +21 -0
- package/README.md +371 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.js +120 -0
- package/package.json +48 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Open Web Foundation
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
<p align="center"><img src=".github/art/cover.jpg" alt="Social Card of this repo"></p>
|
|
2
|
+
|
|
3
|
+
[![npm version][npm-version-src]][npm-version-href]
|
|
4
|
+
[![GitHub Actions][github-actions-src]][github-actions-href]
|
|
5
|
+
[](http://commitizen.github.io/cz-cli/)
|
|
6
|
+
<!-- [![npm downloads][npm-downloads-src]][npm-downloads-href] -->
|
|
7
|
+
<!-- [![Codecov][codecov-src]][codecov-href] -->
|
|
8
|
+
|
|
9
|
+
# BunPress
|
|
10
|
+
|
|
11
|
+
**Fast, modern documentation engine powered by Bun, inspired by VitePress**
|
|
12
|
+
|
|
13
|
+
BunPress is a lightning-fast static site generator designed specifically for documentation. Built on top of Bun's blazing performance with a developer-friendly API inspired by VitePress.
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
### Core Features
|
|
18
|
+
|
|
19
|
+
- ⚡ **Lightning Fast** - 0.18s build time (4,000 files), 11x faster than Eleventy
|
|
20
|
+
- 📝 **Rich Markdown** - VitePress-compatible markdown with containers, alerts, code groups, and syntax highlighting
|
|
21
|
+
- 📋 **Smart TOC** - Automatic table of contents with filtering, positioning (sidebar/inline/floating), and interactive navigation
|
|
22
|
+
- 🛠️ **Developer Friendly** - Native TypeScript support, comprehensive CLI (15+ commands), and extensive customization
|
|
23
|
+
|
|
24
|
+
### SEO & Analytics
|
|
25
|
+
|
|
26
|
+
- 🔍 **Complete SEO** - Auto-generated sitemap.xml, robots.txt, Open Graph tags, and JSON-LD structured data
|
|
27
|
+
- 📊 **Fathom Analytics** - Privacy-focused analytics with GDPR/CCPA compliance and DNT support
|
|
28
|
+
- 🔎 **SEO Validation** - Built-in SEO checker with auto-fix mode for common issues
|
|
29
|
+
|
|
30
|
+
### Markdown Extensions (VitePress-Compatible)
|
|
31
|
+
|
|
32
|
+
- ✅ Custom containers (info, tip, warning, danger, details, raw)
|
|
33
|
+
- ✅ GitHub-flavored alerts (note, tip, important, warning, caution)
|
|
34
|
+
- ✅ Code features (line highlighting, line numbers, focus, diffs, errors/warnings, groups)
|
|
35
|
+
- ✅ Code imports from files with line ranges and regions
|
|
36
|
+
- ✅ Tables with alignment and formatting
|
|
37
|
+
- ✅ Image enhancements with captions and lazy loading
|
|
38
|
+
- ✅ Custom header anchors and inline TOC
|
|
39
|
+
- ✅ **STX template syntax** in markdown — dynamic content with `@if`, `@foreach`, `{{ }}`, `<script server>`
|
|
40
|
+
|
|
41
|
+
### Developer Experience
|
|
42
|
+
|
|
43
|
+
- 🚀 **Fast Dev Server** - ~100ms startup, hot reload, and instant feedback
|
|
44
|
+
- 📦 **Small Bundles** - ~45KB per page (HTML + JS + CSS)
|
|
45
|
+
- 💚 **Low Memory** - ~50MB dev server, ~250MB peak for 1000 files
|
|
46
|
+
- 🎯 **15+ CLI Commands** - Build, dev, preview, stats, doctor, SEO check, and more
|
|
47
|
+
|
|
48
|
+
## Quick Start
|
|
49
|
+
|
|
50
|
+
Get started with BunPress in seconds:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Install BunPress
|
|
54
|
+
bun add @stacksjs/bunpress
|
|
55
|
+
|
|
56
|
+
# Create a new documentation site
|
|
57
|
+
mkdir my-docs
|
|
58
|
+
cd my-docs
|
|
59
|
+
|
|
60
|
+
# Initialize with basic structure
|
|
61
|
+
bunx @stacksjs/bunpress init
|
|
62
|
+
|
|
63
|
+
# Start development server
|
|
64
|
+
bun run dev
|
|
65
|
+
|
|
66
|
+
# Build for production
|
|
67
|
+
bun run build
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Basic Usage
|
|
71
|
+
|
|
72
|
+
Create your first documentation page:
|
|
73
|
+
|
|
74
|
+
```markdown
|
|
75
|
+
---
|
|
76
|
+
title: Welcome
|
|
77
|
+
layout: home
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
# Welcome to My Project
|
|
81
|
+
|
|
82
|
+
This is my awesome project documentation built with BunPress!
|
|
83
|
+
|
|
84
|
+
## Quick Links
|
|
85
|
+
|
|
86
|
+
- [Getting Started](/guide/getting-started)
|
|
87
|
+
- [API Reference](/api)
|
|
88
|
+
- [Examples](/examples)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Configure your site in `bunpress.config.ts`:
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
export default {
|
|
95
|
+
title: 'My Documentation',
|
|
96
|
+
description: 'Built with BunPress',
|
|
97
|
+
nav: [
|
|
98
|
+
{ text: 'Home', link: '/' },
|
|
99
|
+
{ text: 'Guide', link: '/guide' },
|
|
100
|
+
{ text: 'API', link: '/api' }
|
|
101
|
+
],
|
|
102
|
+
|
|
103
|
+
// SEO Configuration
|
|
104
|
+
sitemap: {
|
|
105
|
+
enabled: true,
|
|
106
|
+
baseUrl: 'https://mysite.com',
|
|
107
|
+
},
|
|
108
|
+
robots: {
|
|
109
|
+
enabled: true,
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
// Analytics
|
|
113
|
+
fathom: {
|
|
114
|
+
enabled: true,
|
|
115
|
+
siteId: 'YOUR_SITE_ID',
|
|
116
|
+
honorDNT: true,
|
|
117
|
+
},
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## STX Templates in Markdown
|
|
122
|
+
|
|
123
|
+
BunPress supports [STX](https://stx.sh) template syntax directly inside markdown files. This enables dynamic content generation — conditionals, loops, computed values, and more — powered by the STX templating engine.
|
|
124
|
+
|
|
125
|
+
### Server Scripts
|
|
126
|
+
|
|
127
|
+
Define variables and logic in `<script server>` blocks:
|
|
128
|
+
|
|
129
|
+
```markdown
|
|
130
|
+
<script server>
|
|
131
|
+
const features = [
|
|
132
|
+
{ name: 'Fast', desc: 'Built with Zig for maximum performance' },
|
|
133
|
+
{ name: 'Modern', desc: 'ES modules and TypeScript native' },
|
|
134
|
+
{ name: 'Simple', desc: 'Zero config, one binary' },
|
|
135
|
+
]
|
|
136
|
+
const showBeta = false
|
|
137
|
+
</script>
|
|
138
|
+
|
|
139
|
+
# Features
|
|
140
|
+
|
|
141
|
+
@foreach (features as feature)
|
|
142
|
+
### {{ feature.name }}
|
|
143
|
+
|
|
144
|
+
{{ feature.desc }}
|
|
145
|
+
|
|
146
|
+
@endforeach
|
|
147
|
+
|
|
148
|
+
@if (showBeta)
|
|
149
|
+
## Beta Features
|
|
150
|
+
|
|
151
|
+
These features are coming soon.
|
|
152
|
+
@endif
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Available Directives
|
|
156
|
+
|
|
157
|
+
| Directive | Description |
|
|
158
|
+
|-----------|------------|
|
|
159
|
+
| `<script server>` | Define variables and run server-side logic |
|
|
160
|
+
| `{{ expression }}` | Output an escaped expression |
|
|
161
|
+
| `{!! expression !!}` | Output raw (unescaped) HTML |
|
|
162
|
+
| `@if (condition)` / `@else` / `@endif` | Conditional rendering |
|
|
163
|
+
| `@foreach (array as item)` / `@endforeach` | Iterate over arrays |
|
|
164
|
+
| `@foreach (array as item, index)` | Iterate with index |
|
|
165
|
+
| `@for (let i = 0; i < n; i++)` / `@endfor` | C-style for loops |
|
|
166
|
+
| `@include('Component')` | Include STX components |
|
|
167
|
+
|
|
168
|
+
### Frontmatter Access
|
|
169
|
+
|
|
170
|
+
Frontmatter values are automatically available in STX expressions:
|
|
171
|
+
|
|
172
|
+
```markdown
|
|
173
|
+
---
|
|
174
|
+
title: My Page
|
|
175
|
+
author: Chris
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
# {{ title }}
|
|
179
|
+
|
|
180
|
+
Written by {{ author }}.
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Inline Expressions
|
|
184
|
+
|
|
185
|
+
Use expressions anywhere in your markdown:
|
|
186
|
+
|
|
187
|
+
```markdown
|
|
188
|
+
<script server>
|
|
189
|
+
const count = 42
|
|
190
|
+
const items = ['Alpha', 'Beta', 'Gamma']
|
|
191
|
+
</script>
|
|
192
|
+
|
|
193
|
+
There are {{ count }} items and {{ items.length }} categories.
|
|
194
|
+
The sum is {{ 10 + 20 + 12 }}.
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
STX processing happens before markdown conversion, so the output of STX directives is treated as regular markdown and rendered accordingly — headings, lists, bold, code blocks, and all other markdown features work as expected.
|
|
198
|
+
|
|
199
|
+
## CLI Commands
|
|
200
|
+
|
|
201
|
+
BunPress provides a comprehensive CLI for managing your documentation:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
# Development
|
|
205
|
+
bunpress dev # Start dev server with hot reload
|
|
206
|
+
bunpress build # Build for production
|
|
207
|
+
bunpress preview # Preview production build
|
|
208
|
+
|
|
209
|
+
# Content Management
|
|
210
|
+
bunpress new <path> # Create new markdown file
|
|
211
|
+
bunpress init # Initialize new project
|
|
212
|
+
|
|
213
|
+
# Maintenance
|
|
214
|
+
bunpress clean # Remove build artifacts
|
|
215
|
+
bunpress stats # Show documentation statistics
|
|
216
|
+
bunpress doctor # Run diagnostic checks
|
|
217
|
+
|
|
218
|
+
# SEO
|
|
219
|
+
bunpress seo:check # Check SEO for all pages
|
|
220
|
+
bunpress seo:check --fix # Auto-fix SEO issues
|
|
221
|
+
|
|
222
|
+
# Configuration
|
|
223
|
+
bunpress config:show # Show current configuration
|
|
224
|
+
bunpress config:validate # Validate configuration
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Performance Benchmarks
|
|
228
|
+
|
|
229
|
+
BunPress is **the fastest** documentation generator available, powered by Bun's built-in Zig-based markdown parser.
|
|
230
|
+
|
|
231
|
+
### Markdown Engine Benchmarks
|
|
232
|
+
|
|
233
|
+
Real benchmark results comparing BunPress against documentation frameworks and popular markdown engines. All engines configured with equivalent GFM features (tables, strikethrough, task lists, autolinks). Tested on Apple M3 Pro, 18GB RAM, Bun 1.3.10.
|
|
234
|
+
|
|
235
|
+
> **Fairness note:** These results are conservative. Real VitePress adds Shiki syntax highlighting + Vue plugins on top of markdown-it. Real Astro adds Shiki on top of remark/rehype. commonmark.js does not support GFM, so it processes fewer features and appears artificially fast.
|
|
236
|
+
|
|
237
|
+
#### Simple Markdown (paragraph + inline formatting)
|
|
238
|
+
|
|
239
|
+
| Engine | Avg Time | vs BunPress |
|
|
240
|
+
|--------|---------|-------------|
|
|
241
|
+
| **BunPress** | **2.09 µs** | - |
|
|
242
|
+
| commonmark (no GFM) | 3.91 µs | 1.9x slower |
|
|
243
|
+
| Eleventy | 4.93 µs | 2.4x slower |
|
|
244
|
+
| VitePress | 7.87 µs | 3.8x slower |
|
|
245
|
+
| marked | 29.67 µs | 14x slower |
|
|
246
|
+
| showdown | 32.48 µs | 16x slower |
|
|
247
|
+
| micromark | 120.10 µs | 57x slower |
|
|
248
|
+
| Astro | 126.36 µs | 60x slower |
|
|
249
|
+
|
|
250
|
+
#### Real-World Doc Page (~3KB markdown)
|
|
251
|
+
|
|
252
|
+
| Engine | Avg Time | vs BunPress |
|
|
253
|
+
|--------|---------|-------------|
|
|
254
|
+
| **BunPress** | **28.60 µs** | - |
|
|
255
|
+
| commonmark (no GFM) | 101.47 µs | 3.5x slower |
|
|
256
|
+
| Eleventy | 124.67 µs | 4.4x slower |
|
|
257
|
+
| VitePress | 178.68 µs | 6.2x slower |
|
|
258
|
+
| showdown | 791.29 µs | 28x slower |
|
|
259
|
+
| marked | 841.17 µs | 29x slower |
|
|
260
|
+
| micromark | 2.03 ms | 71x slower |
|
|
261
|
+
| Astro | 2.56 ms | 90x slower |
|
|
262
|
+
|
|
263
|
+
#### Large Document Stress Test (~33KB markdown)
|
|
264
|
+
|
|
265
|
+
| Engine | Avg Time | vs BunPress |
|
|
266
|
+
|--------|---------|-------------|
|
|
267
|
+
| **BunPress** | **204.97 µs** | - |
|
|
268
|
+
| commonmark (no GFM) | 1.01 ms | 4.9x slower |
|
|
269
|
+
| Eleventy | 1.07 ms | 5.2x slower |
|
|
270
|
+
| VitePress | 1.40 ms | 6.8x slower |
|
|
271
|
+
| showdown | 12.76 ms | 62x slower |
|
|
272
|
+
| micromark | 21.61 ms | 105x slower |
|
|
273
|
+
| Astro | 26.56 ms | 130x slower |
|
|
274
|
+
| marked | 47.41 ms | 231x slower |
|
|
275
|
+
|
|
276
|
+
#### Throughput: 100 Mixed Documents
|
|
277
|
+
|
|
278
|
+
| Engine | Avg Time | vs BunPress |
|
|
279
|
+
|--------|---------|-------------|
|
|
280
|
+
| **BunPress** | **827.40 µs** | - |
|
|
281
|
+
| commonmark (no GFM) | 3.45 ms | 4.2x slower |
|
|
282
|
+
| Eleventy | 3.80 ms | 4.6x slower |
|
|
283
|
+
| VitePress | 4.85 ms | 5.9x slower |
|
|
284
|
+
| marked | 17.43 ms | 21x slower |
|
|
285
|
+
| showdown | 25.29 ms | 31x slower |
|
|
286
|
+
| micromark | 72.79 ms | 88x slower |
|
|
287
|
+
| Astro | 84.95 ms | 103x slower |
|
|
288
|
+
|
|
289
|
+
### Build Performance (4,000 markdown files)
|
|
290
|
+
|
|
291
|
+
Using the same methodology as [11ty's official performance tests](https://www.11ty.dev/docs/performance/):
|
|
292
|
+
|
|
293
|
+
| Generator | Build Time | vs BunPress |
|
|
294
|
+
|-----------|-----------|-------------|
|
|
295
|
+
| **BunPress** | **0.18s** | - |
|
|
296
|
+
| Eleventy | 1.93s | 11x slower |
|
|
297
|
+
| VitePress | 8.50s | 47x slower |
|
|
298
|
+
| Astro | 22.90s | 130x slower |
|
|
299
|
+
| Gatsby | 29.05s | 165x slower |
|
|
300
|
+
| Next.js | 70.65s | 401x slower |
|
|
301
|
+
|
|
302
|
+
### Full-Featured Build (with syntax highlighting)
|
|
303
|
+
|
|
304
|
+
| Generator | Build Time | vs BunPress |
|
|
305
|
+
|-----------|-----------|-------------|
|
|
306
|
+
| **BunPress** | **4.12s** | - |
|
|
307
|
+
| VitePress | 8.50s | 2x slower |
|
|
308
|
+
| Astro | 22.90s | 5.6x slower |
|
|
309
|
+
| Gatsby | 29.05s | 7x slower |
|
|
310
|
+
| Next.js | 70.65s | 17x slower |
|
|
311
|
+
|
|
312
|
+
Run the benchmarks yourself:
|
|
313
|
+
|
|
314
|
+
```bash
|
|
315
|
+
cd benchmark && bun install && bun run bench
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
## Testing
|
|
319
|
+
|
|
320
|
+
```bash
|
|
321
|
+
bun test # Run all tests
|
|
322
|
+
bun test:quick # Quick test run (10s timeout)
|
|
323
|
+
bun run typecheck # Type checking
|
|
324
|
+
bun run lint # Lint code
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
## Changelog
|
|
328
|
+
|
|
329
|
+
Please see our [releases](https://github.com/stacksjs/bunpress/releases) page for more information on what has changed recently.
|
|
330
|
+
|
|
331
|
+
## Contributing
|
|
332
|
+
|
|
333
|
+
Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details.
|
|
334
|
+
|
|
335
|
+
## Community
|
|
336
|
+
|
|
337
|
+
For help, discussion about best practices, or any other conversation that would benefit from being searchable:
|
|
338
|
+
|
|
339
|
+
[Discussions on GitHub](https://github.com/stacksjs/bunpress/discussions)
|
|
340
|
+
|
|
341
|
+
For casual chit-chat with others using this package:
|
|
342
|
+
|
|
343
|
+
[Join the Stacks Discord Server](https://discord.gg/stacksjs)
|
|
344
|
+
|
|
345
|
+
## Postcardware
|
|
346
|
+
|
|
347
|
+
“Software that is free, but hopes for a postcard.” We love receiving postcards from around the world showing where Stacks is being used! We showcase them on our website too.
|
|
348
|
+
|
|
349
|
+
Our address: Stacks.js, 12665 Village Ln #2306, Playa Vista, CA 90094, United States 🌎
|
|
350
|
+
|
|
351
|
+
## Sponsors
|
|
352
|
+
|
|
353
|
+
We would like to extend our thanks to the following sponsors for funding Stacks development. If you are interested in becoming a sponsor, please reach out to us.
|
|
354
|
+
|
|
355
|
+
- [JetBrains](https://www.jetbrains.com/)
|
|
356
|
+
- [The Solana Foundation](https://solana.com/)
|
|
357
|
+
|
|
358
|
+
## License
|
|
359
|
+
|
|
360
|
+
The MIT License (MIT). Please see [LICENSE](LICENSE.md) for more information.
|
|
361
|
+
|
|
362
|
+
Made with 💙
|
|
363
|
+
|
|
364
|
+
<!-- Badges -->
|
|
365
|
+
[npm-version-src]: https://img.shields.io/npm/v/@stacksjs/bunpress?style=flat-square
|
|
366
|
+
[npm-version-href]: https://npmjs.com/package/@stacksjs/bunpress
|
|
367
|
+
[github-actions-src]: https://img.shields.io/github/actions/workflow/status/stacksjs/bunpress/ci.yml?style=flat-square&branch=main
|
|
368
|
+
[github-actions-href]: https://github.com/stacksjs/bunpress/actions?query=workflow%3Aci
|
|
369
|
+
|
|
370
|
+
<!-- [codecov-src]: https://img.shields.io/codecov/c/gh/stacksjs/bunpress/main?style=flat-square
|
|
371
|
+
[codecov-href]: https://codecov.io/gh/stacksjs/bunpress -->
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create a docs handler for serving bunpress-built documentation
|
|
3
|
+
* within an existing Bun.serve() application.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* const docs = await createDocsHandler({
|
|
8
|
+
* buildDir: './dist/.bunpress',
|
|
9
|
+
* pathPrefix: '/docs',
|
|
10
|
+
* })
|
|
11
|
+
*
|
|
12
|
+
* Bun.serve({
|
|
13
|
+
* fetch(req) {
|
|
14
|
+
* const url = new URL(req.url)
|
|
15
|
+
*
|
|
16
|
+
* // Docs handler
|
|
17
|
+
* if (url.pathname === '/docs' || url.pathname.startsWith('/docs/')) {
|
|
18
|
+
* const res = await docs.fetch(req)
|
|
19
|
+
* if (res) return res
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* // Your other routes...
|
|
23
|
+
* return new Response('Not found', { status: 404 })
|
|
24
|
+
* },
|
|
25
|
+
* })
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare function createDocsHandler(options: DocsHandlerOptions): Promise<DocsHandler>;
|
|
29
|
+
export declare interface DocsHandlerOptions {
|
|
30
|
+
buildDir: string
|
|
31
|
+
pathPrefix?: string
|
|
32
|
+
cacheControl?: string
|
|
33
|
+
}
|
|
34
|
+
export declare interface DocsHandler {
|
|
35
|
+
fetch: (req: Request) => Promise<Response | null>
|
|
36
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/index.ts
|
|
3
|
+
import { readdir } from "fs/promises";
|
|
4
|
+
import { join, resolve } from "path";
|
|
5
|
+
var CONTENT_TYPES = {
|
|
6
|
+
html: "text/html; charset=utf-8",
|
|
7
|
+
css: "text/css; charset=utf-8",
|
|
8
|
+
js: "application/javascript; charset=utf-8",
|
|
9
|
+
json: "application/json",
|
|
10
|
+
svg: "image/svg+xml",
|
|
11
|
+
png: "image/png",
|
|
12
|
+
jpg: "image/jpeg",
|
|
13
|
+
jpeg: "image/jpeg",
|
|
14
|
+
gif: "image/gif",
|
|
15
|
+
ico: "image/x-icon",
|
|
16
|
+
woff: "font/woff",
|
|
17
|
+
woff2: "font/woff2",
|
|
18
|
+
ttf: "font/ttf",
|
|
19
|
+
eot: "application/vnd.ms-fontobject",
|
|
20
|
+
xml: "application/xml",
|
|
21
|
+
txt: "text/plain"
|
|
22
|
+
};
|
|
23
|
+
async function scanDocPages(dir) {
|
|
24
|
+
const pages = new Set(["/"]);
|
|
25
|
+
async function walk(currentDir, currentPrefix) {
|
|
26
|
+
try {
|
|
27
|
+
const entries = await readdir(currentDir, { withFileTypes: true });
|
|
28
|
+
for (const entry of entries) {
|
|
29
|
+
if (entry.isFile() && entry.name.endsWith(".html") && entry.name !== "404.html") {
|
|
30
|
+
const name = entry.name.replace(".html", "");
|
|
31
|
+
pages.add(name === "index" ? currentPrefix || "/" : `${currentPrefix}/${name}`);
|
|
32
|
+
} else if (entry.isDirectory() && !entry.name.startsWith(".")) {
|
|
33
|
+
await walk(join(currentDir, entry.name), `${currentPrefix}/${entry.name}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
} catch {}
|
|
37
|
+
}
|
|
38
|
+
await walk(dir, "");
|
|
39
|
+
return pages;
|
|
40
|
+
}
|
|
41
|
+
function rewriteLinks(html, knownPages, pathPrefix) {
|
|
42
|
+
return html.replace(/href="(\/[^"]*?)"/g, (match, href) => {
|
|
43
|
+
if (knownPages.has(href)) {
|
|
44
|
+
const rewritten = href === "/" ? pathPrefix : `${pathPrefix}${href}`;
|
|
45
|
+
return `href="${rewritten}"`;
|
|
46
|
+
}
|
|
47
|
+
return match;
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
async function createDocsHandler(options) {
|
|
51
|
+
const buildDir = resolve(options.buildDir);
|
|
52
|
+
const pathPrefix = (options.pathPrefix || "/docs").replace(/\/$/, "");
|
|
53
|
+
const cacheControl = options.cacheControl || "public, max-age=3600";
|
|
54
|
+
let pagesCache = null;
|
|
55
|
+
async function getPages() {
|
|
56
|
+
if (pagesCache)
|
|
57
|
+
return pagesCache;
|
|
58
|
+
pagesCache = await scanDocPages(buildDir);
|
|
59
|
+
return pagesCache;
|
|
60
|
+
}
|
|
61
|
+
async function resolveFile(subPath) {
|
|
62
|
+
const candidates = [
|
|
63
|
+
resolve(buildDir, `.${subPath}`),
|
|
64
|
+
resolve(buildDir, `.${subPath}.html`),
|
|
65
|
+
resolve(buildDir, `.${subPath}/index.html`)
|
|
66
|
+
];
|
|
67
|
+
for (const candidate of candidates) {
|
|
68
|
+
const file = Bun.file(candidate);
|
|
69
|
+
if (await file.exists()) {
|
|
70
|
+
return { file, path: candidate };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
async function serveHtml(file) {
|
|
76
|
+
const pages = await getPages();
|
|
77
|
+
const html = rewriteLinks(await file.text(), pages, pathPrefix);
|
|
78
|
+
return new Response(html, {
|
|
79
|
+
headers: {
|
|
80
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
81
|
+
"Cache-Control": cacheControl
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
async fetch(req) {
|
|
87
|
+
const url = new URL(req.url);
|
|
88
|
+
const reqPath = url.pathname;
|
|
89
|
+
let subPath;
|
|
90
|
+
if (reqPath === pathPrefix || reqPath === `${pathPrefix}/`) {
|
|
91
|
+
subPath = "/index.html";
|
|
92
|
+
} else if (reqPath.startsWith(`${pathPrefix}/`)) {
|
|
93
|
+
subPath = reqPath.slice(pathPrefix.length);
|
|
94
|
+
} else {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
const resolved = await resolveFile(subPath);
|
|
98
|
+
if (resolved) {
|
|
99
|
+
const ext = resolved.path.split(".").pop()?.toLowerCase() || "";
|
|
100
|
+
if (ext === "html") {
|
|
101
|
+
return serveHtml(resolved.file);
|
|
102
|
+
}
|
|
103
|
+
return new Response(resolved.file, {
|
|
104
|
+
headers: {
|
|
105
|
+
"Content-Type": CONTENT_TYPES[ext] || "application/octet-stream",
|
|
106
|
+
"Cache-Control": cacheControl
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
const indexFile = Bun.file(resolve(buildDir, "index.html"));
|
|
111
|
+
if (await indexFile.exists()) {
|
|
112
|
+
return serveHtml(indexFile);
|
|
113
|
+
}
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
export {
|
|
119
|
+
createDocsHandler
|
|
120
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "bun-plugin-bunpress",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.1.3",
|
|
5
|
+
"description": "Serve bunpress-built documentation within any Bun.serve() application.",
|
|
6
|
+
"author": "Chris Breuer <chris@stacksjs.org>",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"homepage": "https://github.com/stacksjs/bunpress/tree/main/packages/bun-plugin-bunpress#readme",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/stacksjs/bunpress.git",
|
|
12
|
+
"directory": "packages/bun-plugin-bunpress"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/stacksjs/bunpress/issues"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"bunpress",
|
|
19
|
+
"bun",
|
|
20
|
+
"plugin",
|
|
21
|
+
"documentation",
|
|
22
|
+
"serve",
|
|
23
|
+
"static-site"
|
|
24
|
+
],
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"import": "./dist/index.js"
|
|
29
|
+
},
|
|
30
|
+
"./*": {
|
|
31
|
+
"import": "./dist/*"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"module": "./dist/index.js",
|
|
35
|
+
"types": "./dist/index.d.ts",
|
|
36
|
+
"files": [
|
|
37
|
+
"README.md",
|
|
38
|
+
"dist"
|
|
39
|
+
],
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "bun --bun build.ts",
|
|
42
|
+
"prepublishOnly": "bun --bun run build",
|
|
43
|
+
"typecheck": "bun --bun tsc --noEmit"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"typescript": "^5.9.3"
|
|
47
|
+
}
|
|
48
|
+
}
|