bunki 0.18.0 → 0.18.5
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/README.md +117 -1
- package/dist/cli/commands/images-push.d.ts +3 -1
- package/dist/cli/commands/validate-media.d.ts +9 -0
- package/dist/cli.js +24332 -24026
- package/dist/constants.d.ts +47 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +618 -513
- package/dist/types.d.ts +39 -2
- package/dist/utils/build-cache.d.ts +2 -1
- package/dist/utils/image-uploader.d.ts +1 -0
- package/dist/utils/json-ld.d.ts +6 -0
- package/dist/utils/markdown/constants.d.ts +2 -0
- package/dist/utils/s3-uploader.d.ts +1 -1
- package/dist/utils/schema-factory.d.ts +58 -0
- package/dist/utils/template-engine.d.ts +19 -0
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -541,6 +541,54 @@ This is useful for:
|
|
|
541
541
|
- Testing uploads for specific years
|
|
542
542
|
- Managing large image collections across multiple uploads
|
|
543
543
|
|
|
544
|
+
#### `--content-assets`
|
|
545
|
+
|
|
546
|
+
Upload images that are co-located with markdown files instead of the top-level `assets/` directory.
|
|
547
|
+
|
|
548
|
+
When content is organized with images living alongside the markdown:
|
|
549
|
+
|
|
550
|
+
```
|
|
551
|
+
content/
|
|
552
|
+
├── 2024/
|
|
553
|
+
│ └── _assets/
|
|
554
|
+
│ ├── paris-cafe.webp
|
|
555
|
+
│ └── eiffel-tower.webp
|
|
556
|
+
└── 2025/
|
|
557
|
+
└── _assets/
|
|
558
|
+
└── tokyo-ramen.webp
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
Run:
|
|
562
|
+
|
|
563
|
+
```bash
|
|
564
|
+
bunki images:push --content-assets
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
This uploads each file with the S3 key `{year}/{filename}` — the `_assets/` segment is stripped. For example, `content/2024/_assets/paris-cafe.webp` becomes key `2024/paris-cafe.webp`, accessible at `https://cdn.example.com/2024/paris-cafe.webp`.
|
|
568
|
+
|
|
569
|
+
> [!IMPORTANT]
|
|
570
|
+
> Always use CDN URLs in your markdown, not relative `_assets/` paths. Relative paths cause the image files to be bundled into your Cloudflare Workers deployment instead of served from R2.
|
|
571
|
+
|
|
572
|
+
```markdown
|
|
573
|
+
<!-- ❌ Causes image to be bundled into Workers -->
|
|
574
|
+

|
|
575
|
+
|
|
576
|
+
<!-- ✅ Served from R2 CDN -->
|
|
577
|
+

|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
#### `--content-assets-dir <dir>`
|
|
581
|
+
|
|
582
|
+
Override the assets subdirectory name. Defaults to `_assets` (or `contentAssets.assetsDir` in `bunki.config.ts`).
|
|
583
|
+
|
|
584
|
+
```bash
|
|
585
|
+
# Use _images instead of _assets
|
|
586
|
+
bunki images:push --content-assets --content-assets-dir _images
|
|
587
|
+
|
|
588
|
+
# Use any custom name
|
|
589
|
+
bunki images:push --content-assets --content-assets-dir media
|
|
590
|
+
```
|
|
591
|
+
|
|
544
592
|
### Complete Examples
|
|
545
593
|
|
|
546
594
|
#### Cloudflare R2 Setup
|
|
@@ -746,6 +794,56 @@ Ensure all required environment variables are set. Check `bunki.config.ts` and y
|
|
|
746
794
|
|
|
747
795
|
### Advanced Configuration
|
|
748
796
|
|
|
797
|
+
#### Content Assets Configuration
|
|
798
|
+
|
|
799
|
+
Configure co-located content assets in `bunki.config.ts`:
|
|
800
|
+
|
|
801
|
+
```typescript
|
|
802
|
+
import { SiteConfig } from "bunki";
|
|
803
|
+
|
|
804
|
+
export default (): SiteConfig => ({
|
|
805
|
+
title: "My Blog",
|
|
806
|
+
baseUrl: "https://example.com",
|
|
807
|
+
domain: "example.com",
|
|
808
|
+
|
|
809
|
+
// Default S3 config (used by bunki images:push)
|
|
810
|
+
s3: {
|
|
811
|
+
accessKeyId: process.env.S3_ACCESS_KEY_ID || "",
|
|
812
|
+
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY || "",
|
|
813
|
+
bucket: "my-site-assets",
|
|
814
|
+
endpoint: process.env.S3_ENDPOINT,
|
|
815
|
+
region: "auto",
|
|
816
|
+
publicUrl: "https://assets.example.com",
|
|
817
|
+
},
|
|
818
|
+
|
|
819
|
+
// Content assets: images stored alongside markdown in content/{year}/_images/
|
|
820
|
+
contentAssets: {
|
|
821
|
+
// Directory name within content/{year}/ (default: "_assets")
|
|
822
|
+
assetsDir: "_images",
|
|
823
|
+
|
|
824
|
+
// Optional: use a separate R2 bucket for content assets
|
|
825
|
+
s3: {
|
|
826
|
+
accessKeyId: process.env.IMG_ACCESS_KEY_ID || "",
|
|
827
|
+
secretAccessKey: process.env.IMG_SECRET_ACCESS_KEY || "",
|
|
828
|
+
bucket: "my-blog-images",
|
|
829
|
+
endpoint: process.env.S3_ENDPOINT,
|
|
830
|
+
region: "auto",
|
|
831
|
+
publicUrl: "https://img.example.com",
|
|
832
|
+
},
|
|
833
|
+
},
|
|
834
|
+
});
|
|
835
|
+
```
|
|
836
|
+
|
|
837
|
+
Then upload content assets:
|
|
838
|
+
|
|
839
|
+
```bash
|
|
840
|
+
# Uses contentAssets.assetsDir and contentAssets.s3 from config
|
|
841
|
+
bunki images:push --content-assets
|
|
842
|
+
|
|
843
|
+
# Override the directory name at the CLI level
|
|
844
|
+
bunki images:push --content-assets --content-assets-dir _media
|
|
845
|
+
```
|
|
846
|
+
|
|
749
847
|
#### Custom Domain per Bucket
|
|
750
848
|
|
|
751
849
|
If you have multiple S3 buckets with different custom domains:
|
|
@@ -806,10 +904,12 @@ Bunki supports incremental builds for significantly faster rebuild times during
|
|
|
806
904
|
### Performance Impact
|
|
807
905
|
|
|
808
906
|
**Large site example (455 posts):**
|
|
907
|
+
|
|
809
908
|
- Full build: 3,128ms
|
|
810
909
|
- Incremental build (no changes): 985ms (**3.2x faster**)
|
|
811
910
|
|
|
812
911
|
**Speedup breakdown:**
|
|
912
|
+
|
|
813
913
|
- Markdown parsing: 1,202ms → 55ms (**22x faster**)
|
|
814
914
|
- CSS processing: 1,024ms → 1ms (**1024x faster**)
|
|
815
915
|
- Overall: **68% faster builds**
|
|
@@ -873,11 +973,13 @@ echo ".bunki-cache.json" >> .gitignore
|
|
|
873
973
|
### When to Use
|
|
874
974
|
|
|
875
975
|
**Recommended for:**
|
|
976
|
+
|
|
876
977
|
- Large sites (100+ posts)
|
|
877
978
|
- Development workflow with frequent rebuilds
|
|
878
979
|
- Sites with slow CSS processing (Tailwind, PostCSS)
|
|
879
980
|
|
|
880
981
|
**Not needed for:**
|
|
982
|
+
|
|
881
983
|
- Small sites (<50 posts) - already fast enough
|
|
882
984
|
- CI/CD builds - prefer clean full builds
|
|
883
985
|
- Production deployments - always use full builds
|
|
@@ -912,6 +1014,7 @@ Version 2.0.0 cache structure:
|
|
|
912
1014
|
### Future Optimizations
|
|
913
1015
|
|
|
914
1016
|
Current implementation (v0.18.0) optimizes parsing and CSS processing. Future versions may add:
|
|
1017
|
+
|
|
915
1018
|
- Selective page regeneration (only rebuild changed posts)
|
|
916
1019
|
- Incremental sitemap/RSS updates
|
|
917
1020
|
- Smart index page regeneration
|
|
@@ -1092,7 +1195,20 @@ bunki/
|
|
|
1092
1195
|
|
|
1093
1196
|
## Changelog
|
|
1094
1197
|
|
|
1095
|
-
### v0.18.
|
|
1198
|
+
### v0.18.1 (Current)
|
|
1199
|
+
|
|
1200
|
+
- **Page Generation Optimization**: Cache JSON-LD schemas and metadata during initialization
|
|
1201
|
+
- Eliminates 910 redundant operations per build (455 posts × 2)
|
|
1202
|
+
- `extractFirstImageUrl()` called once during initialization, cached in `post.image`
|
|
1203
|
+
- Word count calculated once, cached in `post.wordCount`
|
|
1204
|
+
- JSON-LD schemas pre-generated and cached in `post.jsonLd`
|
|
1205
|
+
- Removed duplicate schema generation from page and feed generators
|
|
1206
|
+
- **Deployment Optimization**: All deploy commands now use incremental builds by default
|
|
1207
|
+
- `deploy:all` now builds incrementally for faster deployments
|
|
1208
|
+
- Individual site deployments also use incremental builds
|
|
1209
|
+
- Full builds available via `build:full` when needed
|
|
1210
|
+
|
|
1211
|
+
### v0.18.0
|
|
1096
1212
|
|
|
1097
1213
|
- **Incremental Builds**: Smart caching for 3.2x faster development builds
|
|
1098
1214
|
- File change detection using content hashing and modification times
|
|
@@ -7,9 +7,11 @@ interface ImagesPushDeps {
|
|
|
7
7
|
}
|
|
8
8
|
export declare function handleImagesPushCommand(options: {
|
|
9
9
|
domain?: string;
|
|
10
|
-
images
|
|
10
|
+
images?: string;
|
|
11
11
|
outputJson?: string;
|
|
12
12
|
minYear?: string;
|
|
13
|
+
contentAssets?: boolean;
|
|
14
|
+
contentAssetsDir?: string;
|
|
13
15
|
}, deps?: ImagesPushDeps): Promise<void>;
|
|
14
16
|
export declare function registerImagesPushCommand(program: Command): Command;
|
|
15
17
|
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
export declare function handleValidateMediaCommand(options: {
|
|
3
|
+
contentDir?: string;
|
|
4
|
+
fix?: boolean;
|
|
5
|
+
}, deps?: {
|
|
6
|
+
logger: Console;
|
|
7
|
+
exit: (code: number) => never;
|
|
8
|
+
}): Promise<void>;
|
|
9
|
+
export declare function registerValidateMediaCommand(program: Command): Command;
|