bunki 0.1.3 → 0.2.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 (4) hide show
  1. package/README.md +196 -17
  2. package/dist/cli.js +9006 -141
  3. package/dist/index.js +8867 -14
  4. package/package.json +7 -7
package/README.md CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  [![GitHub license](https://img.shields.io/github/license/kahwee/bunki)](https://github.com/kahwee/bunki/blob/main/LICENSE)
4
4
  [![GitHub issues](https://img.shields.io/github/issues/kahwee/bunki)](https://github.com/kahwee/bunki/issues)
5
- [![Coverage Status](https://coveralls.io/repos/github/kahwee/bunki/badge.svg?branch=main)](https://coveralls.io/github/kahwee/bunki?branch=main)
6
5
 
7
6
  Bunki is an opinionated static site generator built with Bun. It's designed for creating blogs and simple websites with sensible defaults and minimal configuration.
8
7
 
@@ -17,10 +16,11 @@ Bunki is an opinionated static site generator built with Bun. It's designed for
17
16
  - Sitemap generation
18
17
  - Local development server
19
18
  - Simple CLI interface
19
+ - Cloud image uploading via Cloudflare R2
20
20
 
21
21
  ## Installation
22
22
 
23
- > **IMPORTANT**: Bunki requires Bun v1.2.11 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 and will not work with npm, yarn, or pnpm.
24
24
 
25
25
  ### Prerequisites
26
26
 
@@ -28,11 +28,11 @@ Bunki is an opinionated static site generator built with Bun. It's designed for
28
28
  # Install Bun if you don't have it
29
29
  curl -fsSL https://bun.sh/install | bash
30
30
 
31
- # Verify Bun version (should be 1.2.11 or later)
31
+ # Verify Bun version (should be 1.2.12 or later)
32
32
  bun --version
33
33
  ```
34
34
 
35
- ### From npm (Coming soon)
35
+ ### From bun
36
36
 
37
37
  ```bash
38
38
  # Install globally
@@ -70,7 +70,7 @@ bunki init
70
70
 
71
71
  This will:
72
72
 
73
- - Create a default configuration file (`bunki.config.json`)
73
+ - Create a default configuration file (`bunki.config.ts`)
74
74
  - Set up the required directory structure
75
75
  - Create default templates
76
76
  - Add a sample blog post
@@ -113,22 +113,115 @@ Then visit http://localhost:3000 in your browser.
113
113
 
114
114
  ## Configuration
115
115
 
116
- The `bunki.config.json` file contains the configuration for your site:
116
+ The `bunki.config.ts` file contains the configuration for your site:
117
+
118
+ ```typescript
119
+ import { SiteConfig } from "bunki";
120
+ import { config } from "dotenv";
121
+
122
+ // Load environment variables from .env file
123
+ config();
124
+
125
+ export default function (): SiteConfig {
126
+ return {
127
+ title: "My Blog",
128
+ description: "A blog built with Bunki",
129
+ baseUrl: "https://example.com",
130
+ domain: "blog",
131
+ // S3 upload configuration
132
+ 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",
138
+ },
139
+ };
140
+ }
141
+ ```
142
+
143
+ ### Image Upload Configuration
144
+
145
+ Bunki supports uploading images to cloud storage with two implementation options:
146
+
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
149
+
150
+ To configure image uploading to Cloudflare R2 or any S3-compatible service, set the following environment variables:
151
+
152
+ ```
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
157
+ ```
158
+
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:
162
+
163
+ ```
164
+ R2_CUSTOM_DOMAIN_EXAMPLE_COM=cdn.example.com
165
+ ```
166
+
167
+ This will use `https://cdn.example.com/` as the base URL for all uploaded images.
117
168
 
118
- ```json
119
- {
120
- "title": "My Blog",
121
- "description": "A blog built with Bunki",
122
- "baseUrl": "https://example.com",
123
- "domain": "blog"
169
+ #### Selecting an Uploader Implementation
170
+
171
+ When using the CLI, specify the type with the `--type` option:
172
+
173
+ ```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:
190
+
191
+ ```javascript
192
+ import { createUploader } from "bunki";
193
+
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.
124
212
  }
213
+
214
+ // Finalize the upload
215
+ await writer.end();
125
216
  ```
126
217
 
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.
219
+
127
220
  ## Directory Structure
128
221
 
129
222
  ```
130
223
  .
131
- ├── bunki.config.json # Configuration file
224
+ ├── bunki.config.ts # Configuration file
132
225
  ├── content/ # Markdown content
133
226
  │ ├── post1.md
134
227
  │ └── post2.md
@@ -143,6 +236,7 @@ The `bunki.config.json` file contains the configuration for your site:
143
236
  │ └── main.css
144
237
  ├── public/ # Static files to copy to the site
145
238
  │ └── favicon.ico
239
+ ├── images/ # Image storage directory
146
240
  └── dist/ # Generated site
147
241
  ├── index.html
148
242
  ├── css/
@@ -170,6 +264,7 @@ Commands:
170
264
  new [options] <title> Create a new blog post
171
265
  generate [options] Generate static site from markdown content
172
266
  serve [options] Start a local development server
267
+ images:push [options] Upload images to remote storage (e.g., Cloudflare R2)
173
268
  help [command] display help for command
174
269
  ```
175
270
 
@@ -181,7 +276,7 @@ Usage: bunki init [options]
181
276
  Initialize a new site with default structure
182
277
 
183
278
  Options:
184
- -c, --config <file> Path to config file (default: "bunki.config.json")
279
+ -c, --config <file> Path to config file (default: "bunki.config.ts")
185
280
  -h, --help display help for command
186
281
  ```
187
282
 
@@ -208,7 +303,7 @@ Usage: bunki generate [options]
208
303
  Generate static site from markdown content
209
304
 
210
305
  Options:
211
- -c, --config <file> Config file path (default: "bunki.config.json")
306
+ -c, --config <file> Config file path (default: "bunki.config.ts")
212
307
  -c, --content <dir> Content directory (default: "content")
213
308
  -o, --output <dir> Output directory (default: "dist")
214
309
  -t, --templates <dir> Templates directory (default: "templates")
@@ -228,16 +323,56 @@ Options:
228
323
  -h, --help display help for command
229
324
  ```
230
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
+
231
364
  ## Programmatic Usage
232
365
 
233
366
  You can also use Bunki programmatically in your own Bun scripts:
234
367
 
368
+ ### Site Generation
369
+
235
370
  ```javascript
236
371
  import { SiteGenerator, loadConfig } from "bunki";
237
372
  import path from "path";
238
373
 
239
374
  // Load configuration
240
- const config = loadConfig("bunki.config.json");
375
+ const config = loadConfig("bunki.config.ts");
241
376
 
242
377
  // Create a generator
243
378
  const generator = new SiteGenerator({
@@ -257,6 +392,47 @@ async function generate() {
257
392
  generate().catch(console.error);
258
393
  ```
259
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
+
260
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.
261
437
 
262
438
  ## Development
@@ -278,9 +454,12 @@ bun test --watch
278
454
 
279
455
  # Run tests with coverage
280
456
  bun test:coverage
457
+
458
+ # Run TypeScript type checking
459
+ bun run typecheck
281
460
  ```
282
461
 
283
- Code coverage reports are automatically generated and displayed on GitHub through a badge at the top of this README. You can also view detailed coverage reports on [Coveralls](https://coveralls.io/github/kahwee/bunki).
462
+ Code coverage reports are automatically generated during testing.
284
463
 
285
464
  Tests are written using Bun's native test runner and verify all core functionality of Bunki, including:
286
465