bunki 0.2.2 → 0.2.4

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 (2) hide show
  1. package/README.md +39 -329
  2. package/package.json +6 -5
package/README.md CHANGED
@@ -16,11 +16,11 @@ Bunki is an opinionated static site generator built with Bun. It's designed for
16
16
  - Sitemap generation
17
17
  - Local development server
18
18
  - Simple CLI interface
19
- - Cloud image uploading via Cloudflare R2
19
+ - Cloud image uploading (Cloudflare R2, S3)
20
20
 
21
21
  ## Installation
22
22
 
23
- > **IMPORTANT**: Bunki requires Bun v1.2.12 or later as its runtime. It is not compatible with Node.js and will not work with npm, yarn, or pnpm.
23
+ > **IMPORTANT**: Bunki requires Bun v1.2.12 or later as its runtime. It is not compatible with Node.js.
24
24
 
25
25
  ### Prerequisites
26
26
 
@@ -32,7 +32,7 @@ curl -fsSL https://bun.sh/install | bash
32
32
  bun --version
33
33
  ```
34
34
 
35
- ### From bun
35
+ ### Installation Options
36
36
 
37
37
  ```bash
38
38
  # Install globally
@@ -40,22 +40,12 @@ bun install -g bunki
40
40
 
41
41
  # Or install locally in your project
42
42
  bun install bunki
43
- ```
44
-
45
- ### From GitHub
46
43
 
47
- ```bash
48
- # Clone the repository
44
+ # Or from GitHub
49
45
  git clone git@github.com:kahwee/bunki.git
50
46
  cd bunki
51
-
52
- # Install dependencies
53
47
  bun install
54
-
55
- # Build the project
56
48
  bun run build
57
-
58
- # Link for local development
59
49
  bun link
60
50
  ```
61
51
 
@@ -68,13 +58,6 @@ bun link
68
58
  bunki init
69
59
  ```
70
60
 
71
- This will:
72
-
73
- - Create a default configuration file (`bunki.config.ts`)
74
- - Set up the required directory structure
75
- - Create default templates
76
- - Add a sample blog post
77
-
78
61
  ### Add Content
79
62
 
80
63
  Create markdown files in the `content` directory with frontmatter:
@@ -82,7 +65,7 @@ Create markdown files in the `content` directory with frontmatter:
82
65
  ```markdown
83
66
  ---
84
67
  title: Your Post Title
85
- date: 2025-01-01T12:00:00Z
68
+ date: 2025-01-01T09:00:00-07:00
86
69
  tags: [tag1, tag2]
87
70
  ---
88
71
 
@@ -109,8 +92,6 @@ bunki generate
109
92
  bunki serve
110
93
  ```
111
94
 
112
- Then visit http://localhost:3000 in your browser.
113
-
114
95
  ## Configuration
115
96
 
116
97
  The `bunki.config.ts` file contains the configuration for your site:
@@ -130,92 +111,51 @@ export default function (): SiteConfig {
130
111
  domain: "blog",
131
112
  // S3 upload configuration
132
113
  s3: {
133
- accessKeyId: process.env.S3_ACCESS_KEY_ID || "",
134
- secretAccessKey: process.env.S3_SECRET_ACCESS_KEY || "",
135
- bucket: process.env.S3_BUCKET || "",
136
- endpoint: process.env.S3_ENDPOINT,
137
- region: process.env.S3_REGION || "auto",
114
+ accessKeyId: process.env.R2_ACCESS_KEY_ID || "",
115
+ secretAccessKey: process.env.R2_SECRET_ACCESS_KEY || "",
116
+ bucket: process.env.R2_BUCKET || "",
117
+ endpoint: process.env.R2_ENDPOINT,
118
+ region: process.env.R2_REGION || "auto",
119
+ publicUrl: process.env.R2_PUBLIC_URL || "",
138
120
  },
139
121
  };
140
122
  }
141
123
  ```
142
124
 
143
- ### Image Upload Configuration
144
-
145
- Bunki supports uploading images to cloud storage with two implementation options:
125
+ ## Image Upload Configuration
146
126
 
147
- 1. **AWS SDK-based uploader** (type: `r2`) - Uses the AWS SDK for S3-compatible services
148
- 2. **Bun native S3 uploader** (type: `bun-s3` or `bun-r2`) - Uses Bun's built-in S3 API for better performance
127
+ Bunki uses Bun's native S3 API for efficient image uploads to S3-compatible services like Cloudflare R2.
149
128
 
150
- To configure image uploading to Cloudflare R2 or any S3-compatible service, set the following environment variables:
129
+ Configure image uploading by setting environment variables:
151
130
 
152
131
  ```
153
- R2_ACCOUNT_ID=your-cloudflare-account-id
154
- R2_ACCESS_KEY_ID=your-r2-access-key-id
155
- R2_SECRET_ACCESS_KEY=your-r2-secret-access-key
156
- R2_PUBLIC_URL=https://your-r2-public-url.com
132
+ R2_ACCOUNT_ID=your-account-id
133
+ R2_ACCESS_KEY_ID=your-access-key
134
+ R2_SECRET_ACCESS_KEY=your-secret-key
135
+ R2_BUCKET=your-bucket
136
+ R2_PUBLIC_URL=https://your-public-url.com
157
137
  ```
158
138
 
159
- You can add these to a `.env` file in your project root. The bucket name will be automatically generated from your domain name (e.g., `example.com` becomes `example-com`).
160
-
161
- For domain-specific custom domains, you can optionally set:
139
+ For domain-specific custom domains:
162
140
 
163
141
  ```
164
142
  R2_CUSTOM_DOMAIN_EXAMPLE_COM=cdn.example.com
165
143
  ```
166
144
 
167
- This will use `https://cdn.example.com/` as the base URL for all uploaded images.
168
-
169
- #### Selecting an Uploader Implementation
170
-
171
- When using the CLI, specify the type with the `--type` option:
145
+ ### Image Upload Commands
172
146
 
173
147
  ```bash
174
- # Use AWS SDK-based uploader (default)
175
- bunki images:push --type r2
176
-
177
- # Use Bun's native S3 API (faster performance)
178
- bunki images:push --type bun-s3
179
- # or
180
- bunki images:push --type bun-r2
181
- ```
182
-
183
- The Bun native S3 uploader provides better performance and reduced memory usage, especially for large files.
184
-
185
- #### Large File Uploads
186
-
187
- For very large files, the Bun native S3 uploader (`bun-s3` or `bun-r2`) supports efficient chunked uploads using streaming. This is particularly useful for video files, high-resolution images, or other large assets.
188
-
189
- When using the Bun native implementation programmatically, you can leverage the multipart upload functionality:
148
+ # Upload all images
149
+ bunki images:push
190
150
 
191
- ```javascript
192
- import { createUploader } from "bunki";
151
+ # Specify a different images directory
152
+ bunki images:push --images path/to/images
193
153
 
194
- // Create uploader instance
195
- const uploader = createUploader("bun-s3", uploaderConfig);
196
-
197
- // Option 1: Use the high-level large file upload method
198
- const fileUrl = await uploader.uploadLargeFile(
199
- "/path/to/large-video.mp4",
200
- "videos/large-video.mp4",
201
- );
202
-
203
- // Option 2: For more control, use the streaming writer
204
- const writer = uploader.getWriterForLargeFile(
205
- "videos/large-video.mp4",
206
- "video/mp4",
207
- );
208
-
209
- // Write data in chunks
210
- for (let i = 0; i < 100; i++) {
211
- writer.write(chunk); // chunk can be Uint8Array, Buffer, string, etc.
212
- }
213
-
214
- // Finalize the upload
215
- await writer.end();
154
+ # Output URL mapping to a JSON file
155
+ bunki images:push --output-json image-urls.json
216
156
  ```
217
157
 
218
- The AWS SDK implementation (`r2`) also supports large file uploads through its own multipart upload mechanism, but doesn't provide the streaming writer interface.
158
+ The image uploader supports JPG, PNG, GIF, WebP, and SVG formats.
219
159
 
220
160
  ## Directory Structure
221
161
 
@@ -223,8 +163,8 @@ The AWS SDK implementation (`r2`) also supports large file uploads through its o
223
163
  .
224
164
  ├── bunki.config.ts # Configuration file
225
165
  ├── content/ # Markdown content
226
- ├── post1.md
227
- └── post2.md
166
+ └── YYYY/ # Year-based organization
167
+ └── post-slug.md
228
168
  ├── templates/ # Nunjucks templates
229
169
  │ ├── base.njk
230
170
  │ ├── index.njk
@@ -234,267 +174,37 @@ The AWS SDK implementation (`r2`) also supports large file uploads through its o
234
174
  │ ├── archive.njk
235
175
  │ └── styles/
236
176
  │ └── main.css
237
- ├── public/ # Static files to copy to the site
238
- │ └── favicon.ico
239
- ├── images/ # Image storage directory
177
+ ├── images/ # Local images directory
240
178
  └── dist/ # Generated site
241
- ├── index.html
242
- ├── css/
243
- │ └── style.css
244
- └── ...
245
179
  ```
246
180
 
247
- ## Templates
248
-
249
- Bunki uses [Nunjucks](https://mozilla.github.io/nunjucks/) for templating. The templates should be placed in the `templates` directory. The default templates provide a solid starting point for most blogs.
250
-
251
- ## Command Line Interface
181
+ ## CLI Commands
252
182
 
253
183
  ```
254
184
  Usage: bunki [options] [command]
255
185
 
256
- An opinionated static site generator built with Bun
257
-
258
- Options:
259
- -V, --version output the version number
260
- -h, --help display help for command
261
-
262
186
  Commands:
263
- init [options] Initialize a new site with default structure
187
+ init [options] Initialize a new site
264
188
  new [options] <title> Create a new blog post
265
- generate [options] Generate static site from markdown content
266
- serve [options] Start a local development server
267
- images:push [options] Upload images to remote storage (e.g., Cloudflare R2)
268
- help [command] display help for command
269
- ```
270
-
271
- ### Initialize Command
272
-
273
- ```
274
- Usage: bunki init [options]
275
-
276
- Initialize a new site with default structure
277
-
278
- Options:
279
- -c, --config <file> Path to config file (default: "bunki.config.ts")
280
- -h, --help display help for command
281
- ```
282
-
283
- ### New Post Command
284
-
285
- ```
286
- Usage: bunki new [options] <title>
287
-
288
- Create a new blog post
289
-
290
- Arguments:
291
- title Title of the post
292
-
293
- Options:
294
- -t, --tags <tags> Comma-separated list of tags (default: "")
295
- -h, --help display help for command
296
- ```
297
-
298
- ### Generate Command
299
-
300
- ```
301
- Usage: bunki generate [options]
302
-
303
- Generate static site from markdown content
304
-
305
- Options:
306
- -c, --config <file> Config file path (default: "bunki.config.ts")
307
- -c, --content <dir> Content directory (default: "content")
308
- -o, --output <dir> Output directory (default: "dist")
309
- -t, --templates <dir> Templates directory (default: "templates")
310
- -h, --help display help for command
311
- ```
312
-
313
- ### Serve Command
314
-
189
+ generate [options] Generate static site
190
+ serve [options] Start development server
191
+ images:push [options] Upload images to storage
192
+ help [command] Display help
315
193
  ```
316
- Usage: bunki serve [options]
317
-
318
- Start a local development server
319
-
320
- Options:
321
- -o, --output <dir> Output directory (default: "dist")
322
- -p, --port <number> Port number (default: "3000")
323
- -h, --help display help for command
324
- ```
325
-
326
- ### Image Upload Commands
327
-
328
- #### Upload Multiple Images
329
-
330
- ```
331
- Usage: bunki images:push [options]
332
-
333
- Upload images to remote storage (e.g., Cloudflare R2)
334
-
335
- Options:
336
- -d, --domain <domain> Domain name (defaults to domain in bunki.config.ts)
337
- -i, --images <dir> Images directory path (default: "images")
338
- -t, --type <type> Upload storage type (r2, bun-s3, bun-r2) (default: "r2")
339
- --output-json <file> Output URL mapping to JSON file
340
- -h, --help display help for command
341
- ```
342
-
343
- This command will find and upload all supported image files (JPG, PNG, GIF, WebP, SVG) in the specified directory.
344
-
345
- #### Quick Upload Script
346
-
347
- Bunki also includes a convenient shell script for quick image uploads:
348
-
349
- ```bash
350
- # Upload a single image using the shell script
351
- ./upload-image.sh path/to/your/image.jpg
352
-
353
- # Optionally specify the domain
354
- ./upload-image.sh path/to/your/image.jpg example.com
355
- ```
356
-
357
- After uploading, the tool will display the public URL of the uploaded image along with the markdown syntax to use it in your content:
358
-
359
- ```
360
- Image uploaded successfully!
361
- Use this URL in your markdown: ![Alt text](https://your-r2-url.com/example-com/image.jpg)
362
- ```
363
-
364
- ## Programmatic Usage
365
-
366
- You can also use Bunki programmatically in your own Bun scripts:
367
-
368
- ### Site Generation
369
-
370
- ```javascript
371
- import { SiteGenerator, loadConfig } from "bunki";
372
- import path from "path";
373
-
374
- // Load configuration
375
- const config = loadConfig("bunki.config.ts");
376
-
377
- // Create a generator
378
- const generator = new SiteGenerator({
379
- contentDir: path.join(process.cwd(), "content"),
380
- outputDir: path.join(process.cwd(), "dist"),
381
- templatesDir: path.join(process.cwd(), "templates"),
382
- config,
383
- });
384
-
385
- // Generate site
386
- async function generate() {
387
- await generator.initialize();
388
- await generator.generate();
389
- console.log("Site generation complete!");
390
- }
391
-
392
- generate().catch(console.error);
393
- ```
394
-
395
- ### Image Uploading
396
-
397
- ```javascript
398
- import { uploadImages, DEFAULT_IMAGES_DIR, createUploader } from "bunki";
399
- import path from "path";
400
-
401
- // Upload all images in a directory
402
- async function uploadAllImages() {
403
- // Upload all images in a directory
404
- const imageUrlMap = await uploadImages({
405
- images: DEFAULT_IMAGES_DIR,
406
- type: "bun-r2", // Use Bun's native S3 API for better performance
407
- outputJson: "image-urls.json",
408
- });
409
-
410
- console.log("Image URLs:", imageUrlMap);
411
-
412
- // For large files, you can access the uploader directly
413
- // Get configuration from bunki.config.json or bunki.config.ts
414
- import { loadConfig } from "bunki";
415
- const config = loadConfig();
416
-
417
- // Create uploader instance
418
- const uploader = createUploader(config.s3);
419
-
420
- // Upload a large file
421
- const largeFileStream = Bun.file(
422
- path.join(process.cwd(), "videos/presentation.mp4"),
423
- );
424
- await uploader.upload(
425
- "videos/presentation.mp4",
426
- largeFileStream,
427
- "video/mp4",
428
- );
429
-
430
- console.log("Large file uploaded successfully");
431
- }
432
-
433
- uploadAllImages().catch(console.error);
434
- ```
435
-
436
- > **Note**: Bunki's programmatic API is designed specifically for Bun and utilizes Bun's native APIs for optimal performance. It will not work in Node.js environments.
437
194
 
438
195
  ## Development
439
196
 
440
- ### Testing
441
-
442
- Bunki includes a comprehensive test suite to verify functionality:
443
-
444
197
  ```bash
445
- # Run all tests
198
+ # Run tests
446
199
  bun test
447
200
 
448
- # Run specific test files
449
- bun test site-generator
450
- bun test utils/markdown
451
-
452
- # Run tests with watch mode
453
- bun test --watch
454
-
455
201
  # Run tests with coverage
456
202
  bun test:coverage
457
203
 
458
- # Run TypeScript type checking
204
+ # Type checking
459
205
  bun run typecheck
460
206
  ```
461
207
 
462
- Code coverage reports are automatically generated during testing.
463
-
464
- Tests are written using Bun's native test runner and verify all core functionality of Bunki, including:
465
-
466
- - Site generation process
467
- - Markdown parsing and rendering
468
- - Configuration handling
469
- - File system utilities
470
- - Template rendering
471
-
472
- ### Test Fixtures
473
-
474
- Bunki comes with a set of test fixtures that are used by the test suite and can also serve as examples:
475
-
476
- The fixture directory includes:
477
-
478
- ```
479
- fixtures/
480
- ├── bunki.config.json # Test configuration file
481
- ├── content/ # Sample markdown content
482
- │ └── 2025/
483
- │ ├── test-post-1.md
484
- │ ├── performance-optimization.md
485
- │ └── migrating-from-gatsby.md
486
- ├── src/
487
- │ └── tags.toml # Tag definitions
488
- └── templates/ # Test templates
489
- ├── base.njk
490
- ├── index.njk
491
- ├── post.njk
492
- └── styles/
493
- └── main.css
494
- ```
495
-
496
- You can use these fixtures as examples for your own Bunki projects.
497
-
498
208
  ## License
499
209
 
500
210
  MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bunki",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "An opinionated static site generator built with Bun",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -12,6 +12,7 @@
12
12
  "test": "bun test",
13
13
  "test:coverage": "bun test --coverage --coverage-reporter=lcov",
14
14
  "format": "prettier --write .",
15
+ "format:check": "prettier --check .",
15
16
  "prepare": "husky",
16
17
  "lint-staged": "lint-staged",
17
18
  "typecheck": "bun tsc --noEmit"
@@ -37,21 +38,21 @@
37
38
  },
38
39
  "homepage": "https://github.com/kahwee/bunki#readme",
39
40
  "dependencies": {
40
- "commander": "^13.1.0",
41
+ "commander": "^14",
41
42
  "gray-matter": "^4.0.3",
42
43
  "highlight.js": "^11.9.0",
43
44
  "marked": "^15.0.11",
44
45
  "marked-highlight": "^2.0.7",
45
46
  "nunjucks": "^3.2.4",
46
- "sanitize-html": "^2.11.0",
47
+ "sanitize-html": "2.17.0",
47
48
  "slugify": "^1.6.6"
48
49
  },
49
50
  "devDependencies": {
50
51
  "@types/nunjucks": "^3.2.5",
51
52
  "@types/sanitize-html": "^2.9.5",
52
- "bun-types": "^1.2.12",
53
+ "bun-types": "1.2.13",
53
54
  "husky": "^9.1.7",
54
- "lint-staged": "^15.5.2",
55
+ "lint-staged": "16.0.0",
55
56
  "prettier": "^3.1.0",
56
57
  "typescript": "^5.2.2"
57
58
  },