bunki 0.18.1 → 0.18.6

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/dist/types.d.ts CHANGED
@@ -94,6 +94,8 @@ export interface CDNConfig {
94
94
  pathPattern: string;
95
95
  /** Whether CDN transformation is enabled */
96
96
  enabled: boolean;
97
+ /** Optional post year for year-based asset paths (e.g., "2025") */
98
+ postYear?: string;
97
99
  }
98
100
  /**
99
101
  * Configuration for the site
@@ -131,6 +133,11 @@ export interface SiteConfig {
131
133
  copyright?: string;
132
134
  /** Strict mode: fail build on parsing errors (default: false) */
133
135
  strictMode?: boolean;
136
+ /**
137
+ * Configuration for content assets stored alongside markdown in content/{year}/{assetsDir}/.
138
+ * When set, `bunki images:push --content-assets` uses this config for uploads.
139
+ */
140
+ contentAssets?: ContentAssetsConfig;
134
141
  /** Additional custom configuration options */
135
142
  [key: string]: any;
136
143
  }
@@ -212,9 +219,10 @@ export interface ImageUploader {
212
219
  * Upload all images from a directory
213
220
  * @param imagesDir Directory containing images to upload
214
221
  * @param minYear Optional minimum year to filter (e.g., 2023 uploads 2023, 2024, etc.)
215
- * @returns Record of image filenames to their public URLs
222
+ * @param keyTransform Optional function to transform relative file path into S3 key
223
+ * @returns Record of S3 keys to their public URLs
216
224
  */
217
- uploadImages(imagesDir: string, minYear?: number): Promise<Record<string, string>>;
225
+ uploadImages(imagesDir: string, minYear?: number, keyTransform?: (relativePath: string) => string): Promise<Record<string, string>>;
218
226
  }
219
227
  /**
220
228
  * S3 configuration type
@@ -228,6 +236,24 @@ export interface S3Config {
228
236
  endpoint?: string;
229
237
  region?: string;
230
238
  }
239
+ /**
240
+ * Configuration for content assets stored alongside markdown files.
241
+ * Assets live in content/{year}/{assetsDir}/ and are uploaded to R2/S3
242
+ * with the key {year}/{filename} (the assetsDir is stripped from the path).
243
+ */
244
+ export interface ContentAssetsConfig {
245
+ /**
246
+ * Directory name within content/{year}/ that contains co-located assets.
247
+ * Defaults to "_assets". Can be set to "_images" or any other name.
248
+ */
249
+ assetsDir?: string;
250
+ /**
251
+ * Override S3/R2 config for content assets uploads.
252
+ * When set, uses this config instead of the site's top-level s3 config.
253
+ * Useful if you store blog images in a separate bucket from site assets.
254
+ */
255
+ s3?: S3Config;
256
+ }
231
257
  /**
232
258
  * Options for image upload
233
259
  */
@@ -236,4 +262,11 @@ export interface ImageUploadOptions {
236
262
  images?: string;
237
263
  outputJson?: string;
238
264
  minYear?: number;
265
+ /** Scan content/{year}/{assetsDir}/ and upload as {year}/{filename} */
266
+ contentAssets?: boolean;
267
+ /**
268
+ * Override the assets directory name used in content-assets mode.
269
+ * Defaults to "_assets" (or contentAssets.assetsDir from config).
270
+ */
271
+ contentAssetsDir?: string;
239
272
  }
@@ -28,7 +28,8 @@ export interface BuildCache {
28
28
  */
29
29
  export declare function hashFile(filePath: string): Promise<string>;
30
30
  /**
31
- * Get file modification time
31
+ * Get file modification time (returns 0 if file doesn't exist)
32
+ * Wrapper around file-utils getFileMtime for backward compatibility
32
33
  */
33
34
  export declare function getFileMtime(filePath: string): Promise<number>;
34
35
  /**
@@ -1,3 +1,4 @@
1
1
  import { ImageUploadOptions } from "../types";
2
2
  export declare const DEFAULT_IMAGES_DIR: string;
3
+ export declare const DEFAULT_CONTENT_DIR: string;
3
4
  export declare function uploadImages(options?: ImageUploadOptions): Promise<Record<string, string>>;
@@ -187,6 +187,12 @@ export declare function generateCollectionPageSchema(options: CollectionPageOpti
187
187
  * // Returns: '<script type="application/ld+json">{"@context":"https://schema.org",...}</script>'
188
188
  */
189
189
  export declare function toScriptTag(jsonLd: SchemaOrgThing): string;
190
+ /**
191
+ * Convert multiple JSON-LD schemas to HTML script tags
192
+ * @param schemas - Array of schema objects
193
+ * @returns HTML string with script tags joined by newlines
194
+ */
195
+ export declare function schemasToHtml(schemas: SchemaOrgThing[]): string;
190
196
  /**
191
197
  * Extracts the first image URL from HTML content
192
198
  *
@@ -4,6 +4,8 @@
4
4
  */
5
5
  export declare const RELATIVE_LINK_REGEX: RegExp;
6
6
  export declare const IMAGE_PATH_REGEX: RegExp;
7
+ export declare const IMAGE_PATH_ASSETS_DIR: RegExp;
8
+ export declare const IMAGE_PATH_ASSETS_SAME_DIR: RegExp;
7
9
  export declare const YOUTUBE_EMBED_REGEX: RegExp;
8
10
  export declare const EXTERNAL_LINK_REGEX: RegExp;
9
11
  export declare const SCHEMA_ORG_PLACE_TYPES: Set<string>;
@@ -19,7 +19,7 @@ export declare class S3Uploader implements Uploader, ImageUploader {
19
19
  * @param concurrency Maximum number of concurrent tasks
20
20
  */
21
21
  private executeWithConcurrency;
22
- uploadImages(imagesDir: string, minYear?: number): Promise<Record<string, string>>;
22
+ uploadImages(imagesDir: string, minYear?: number, keyTransform?: (relativePath: string) => string): Promise<Record<string, string>>;
23
23
  }
24
24
  /**
25
25
  * Create an S3 uploader
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Schema generation factory
3
+ * Simplifies creation of JSON-LD structured data for common page types
4
+ */
5
+ import type { SiteConfig, Post } from "../types";
6
+ /**
7
+ * Options for generating collection page schemas (tag pages, year archives, etc.)
8
+ */
9
+ export interface CollectionSchemaOptions {
10
+ /** Page title */
11
+ title: string;
12
+ /** Page description */
13
+ description: string;
14
+ /** Canonical URL for the page */
15
+ url: string;
16
+ /** Posts included in the collection */
17
+ posts: Post[];
18
+ /** Breadcrumb navigation items */
19
+ breadcrumbs: Array<{
20
+ name: string;
21
+ url: string;
22
+ }>;
23
+ }
24
+ /**
25
+ * Generate JSON-LD schemas for collection pages (tag pages, year archives, etc.)
26
+ *
27
+ * This factory function eliminates duplication when creating schemas for
28
+ * pages that display a collection of posts with breadcrumb navigation.
29
+ *
30
+ * Generates both CollectionPage and BreadcrumbList schemas.
31
+ *
32
+ * @param config - Site configuration
33
+ * @param options - Collection page options
34
+ * @returns HTML-encoded JSON-LD script tags ready for insertion
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * // Tag page schemas
39
+ * const jsonLd = generateCollectionSchemas(config, {
40
+ * title: "JavaScript",
41
+ * description: "Articles about JavaScript",
42
+ * url: "https://example.com/tags/javascript/",
43
+ * posts: tagPosts,
44
+ * breadcrumbs: [
45
+ * { name: "Home", url: "https://example.com/" },
46
+ * { name: "JavaScript", url: "https://example.com/tags/javascript/" }
47
+ * ],
48
+ * });
49
+ * ```
50
+ */
51
+ export declare function generateCollectionSchemas(config: SiteConfig, options: CollectionSchemaOptions): string;
52
+ /**
53
+ * Generate breadcrumb schema for homepage
54
+ *
55
+ * @param config - Site configuration
56
+ * @returns HTML-encoded JSON-LD script tag
57
+ */
58
+ export declare function generateHomeBreadcrumbs(config: SiteConfig): string;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Template engine configuration and setup
3
+ * Centralizes Nunjucks configuration and custom filters
4
+ */
5
+ import nunjucks from "nunjucks";
6
+ /**
7
+ * Create and configure Nunjucks template engine with custom filters
8
+ *
9
+ * @param templatesDir - Directory containing template files
10
+ * @param watch - Enable template watching for development (default: false)
11
+ * @returns Configured Nunjucks environment
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const env = createTemplateEngine("./templates");
16
+ * const html = nunjucks.render("index.njk", { site, posts });
17
+ * ```
18
+ */
19
+ export declare function createTemplateEngine(templatesDir: string, watch?: boolean): nunjucks.Environment;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bunki",
3
- "version": "0.18.1",
3
+ "version": "0.18.6",
4
4
  "description": "An opinionated static site generator built with Bun featuring PostCSS integration and modern web development workflows",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -22,7 +22,7 @@
22
22
  "prepublishOnly": "bun run clean && bun run build && bun run test && bun run typecheck"
23
23
  },
24
24
  "bin": {
25
- "bunki": "./dist/cli.js"
25
+ "bunki": "dist/cli.js"
26
26
  },
27
27
  "keywords": [
28
28
  "static-site-generator",