bunki 0.15.0 → 0.16.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.
package/dist/cli.js CHANGED
@@ -32902,7 +32902,15 @@ core_default.registerLanguage("python", python);
32902
32902
  core_default.registerLanguage("json", json);
32903
32903
  core_default.registerLanguage("swift", swift);
32904
32904
  var noFollowExceptions = new Set;
32905
- function createMarked() {
32905
+ function transformImagePath(relativePath, config) {
32906
+ const match = relativePath.match(/^\.\.\/\.\.\/assets\/(\d{4})\/([^/]+)\/(.+)$/);
32907
+ if (!match)
32908
+ return null;
32909
+ const [, year, slug, filename] = match;
32910
+ const path5 = config.pathPattern.replace("{year}", year).replace("{slug}", slug).replace("{filename}", filename);
32911
+ return `${config.baseUrl}/${path5}`;
32912
+ }
32913
+ function createMarked(cdnConfig) {
32906
32914
  const marked = new B(markedHighlight({
32907
32915
  emptyLangClass: "hljs",
32908
32916
  langPrefix: "hljs language-",
@@ -32951,6 +32959,15 @@ function createMarked() {
32951
32959
  }
32952
32960
  }
32953
32961
  }
32962
+ if (token.type === "image" && cdnConfig?.enabled) {
32963
+ const href = token.href || "";
32964
+ if (href.startsWith("../../assets/")) {
32965
+ const transformed = transformImagePath(href, cdnConfig);
32966
+ if (transformed) {
32967
+ token.href = transformed;
32968
+ }
32969
+ }
32970
+ }
32954
32971
  },
32955
32972
  hooks: {
32956
32973
  preprocess(markdown2) {
@@ -32993,8 +33010,9 @@ function extractExcerpt(content, maxLength = 200) {
32993
33010
  const lastSpace = truncated.lastIndexOf(" ");
32994
33011
  return truncated.substring(0, lastSpace) + "...";
32995
33012
  }
32996
- function convertMarkdownToHtml(markdownContent) {
32997
- const html = marked.parse(markdownContent, { async: false });
33013
+ function convertMarkdownToHtml(markdownContent, cdnConfig) {
33014
+ const markedInstance = cdnConfig ? createMarked(cdnConfig) : marked;
33015
+ const html = markedInstance.parse(markdownContent, { async: false });
32998
33016
  let sanitized = import_sanitize_html.default(html, {
32999
33017
  allowedTags: import_sanitize_html.default.defaults.allowedTags.concat([
33000
33018
  "img",
@@ -33146,7 +33164,7 @@ function validateBusinessLocation(business, filePath) {
33146
33164
  }
33147
33165
  return null;
33148
33166
  }
33149
- async function parseMarkdownFile(filePath) {
33167
+ async function parseMarkdownFile(filePath, cdnConfig) {
33150
33168
  try {
33151
33169
  const fileContent = await readFileAsText(filePath);
33152
33170
  if (fileContent === null) {
@@ -33196,8 +33214,8 @@ async function parseMarkdownFile(filePath) {
33196
33214
  };
33197
33215
  }
33198
33216
  }
33199
- let slug = data.slug || getBaseFilename(filePath);
33200
- const sanitizedHtml = convertMarkdownToHtml(content);
33217
+ let slug = getBaseFilename(filePath);
33218
+ const sanitizedHtml = convertMarkdownToHtml(content, cdnConfig);
33201
33219
  const pacificDate = toPacificTime(data.date);
33202
33220
  const postYear = getPacificYear(data.date);
33203
33221
  const post = {
@@ -33259,11 +33277,11 @@ async function parseMarkdownFile(filePath) {
33259
33277
  }
33260
33278
 
33261
33279
  // src/parser.ts
33262
- async function parseMarkdownDirectory(contentDir, strictMode = false) {
33280
+ async function parseMarkdownDirectory(contentDir, strictMode = false, cdnConfig) {
33263
33281
  try {
33264
33282
  const markdownFiles = await findFilesByPattern("**/*.md", contentDir, true);
33265
33283
  console.log(`Found ${markdownFiles.length} markdown files`);
33266
- const resultsPromises = markdownFiles.map((filePath) => parseMarkdownFile(filePath));
33284
+ const resultsPromises = markdownFiles.map((filePath) => parseMarkdownFile(filePath, cdnConfig));
33267
33285
  const results = await Promise.all(resultsPromises);
33268
33286
  const posts = [];
33269
33287
  const errors = [];
@@ -33611,7 +33629,7 @@ class SiteGenerator {
33611
33629
  }
33612
33630
  }
33613
33631
  const strictMode = this.options.config.strictMode ?? false;
33614
- const posts = await parseMarkdownDirectory(this.options.contentDir, strictMode);
33632
+ const posts = await parseMarkdownDirectory(this.options.contentDir, strictMode, this.options.config.cdn);
33615
33633
  const tags = {};
33616
33634
  posts.forEach((post) => {
33617
33635
  post.tagSlugs = {};
@@ -34410,7 +34428,7 @@ function createUploader(config) {
34410
34428
  }
34411
34429
 
34412
34430
  // src/utils/image-uploader.ts
34413
- var DEFAULT_IMAGES_DIR = path8.join(process.cwd(), "images");
34431
+ var DEFAULT_IMAGES_DIR = path8.join(process.cwd(), "assets");
34414
34432
  async function uploadImages(options2 = {}) {
34415
34433
  try {
34416
34434
  const imagesDir = path8.resolve(options2.images || DEFAULT_IMAGES_DIR);
package/dist/index.js CHANGED
@@ -30520,7 +30520,15 @@ core_default.registerLanguage("python", python);
30520
30520
  core_default.registerLanguage("json", json);
30521
30521
  core_default.registerLanguage("swift", swift);
30522
30522
  var noFollowExceptions = new Set;
30523
- function createMarked() {
30523
+ function transformImagePath(relativePath, config) {
30524
+ const match = relativePath.match(/^\.\.\/\.\.\/assets\/(\d{4})\/([^/]+)\/(.+)$/);
30525
+ if (!match)
30526
+ return null;
30527
+ const [, year, slug, filename] = match;
30528
+ const path2 = config.pathPattern.replace("{year}", year).replace("{slug}", slug).replace("{filename}", filename);
30529
+ return `${config.baseUrl}/${path2}`;
30530
+ }
30531
+ function createMarked(cdnConfig) {
30524
30532
  const marked = new B(markedHighlight({
30525
30533
  emptyLangClass: "hljs",
30526
30534
  langPrefix: "hljs language-",
@@ -30569,6 +30577,15 @@ function createMarked() {
30569
30577
  }
30570
30578
  }
30571
30579
  }
30580
+ if (token.type === "image" && cdnConfig?.enabled) {
30581
+ const href = token.href || "";
30582
+ if (href.startsWith("../../assets/")) {
30583
+ const transformed = transformImagePath(href, cdnConfig);
30584
+ if (transformed) {
30585
+ token.href = transformed;
30586
+ }
30587
+ }
30588
+ }
30572
30589
  },
30573
30590
  hooks: {
30574
30591
  preprocess(markdown2) {
@@ -30611,8 +30628,9 @@ function extractExcerpt(content, maxLength = 200) {
30611
30628
  const lastSpace = truncated.lastIndexOf(" ");
30612
30629
  return truncated.substring(0, lastSpace) + "...";
30613
30630
  }
30614
- function convertMarkdownToHtml(markdownContent) {
30615
- const html = marked.parse(markdownContent, { async: false });
30631
+ function convertMarkdownToHtml(markdownContent, cdnConfig) {
30632
+ const markedInstance = cdnConfig ? createMarked(cdnConfig) : marked;
30633
+ const html = markedInstance.parse(markdownContent, { async: false });
30616
30634
  let sanitized = import_sanitize_html.default(html, {
30617
30635
  allowedTags: import_sanitize_html.default.defaults.allowedTags.concat([
30618
30636
  "img",
@@ -30764,7 +30782,7 @@ function validateBusinessLocation(business, filePath) {
30764
30782
  }
30765
30783
  return null;
30766
30784
  }
30767
- async function parseMarkdownFile(filePath) {
30785
+ async function parseMarkdownFile(filePath, cdnConfig) {
30768
30786
  try {
30769
30787
  const fileContent = await readFileAsText(filePath);
30770
30788
  if (fileContent === null) {
@@ -30814,8 +30832,8 @@ async function parseMarkdownFile(filePath) {
30814
30832
  };
30815
30833
  }
30816
30834
  }
30817
- let slug = data.slug || getBaseFilename(filePath);
30818
- const sanitizedHtml = convertMarkdownToHtml(content);
30835
+ let slug = getBaseFilename(filePath);
30836
+ const sanitizedHtml = convertMarkdownToHtml(content, cdnConfig);
30819
30837
  const pacificDate = toPacificTime(data.date);
30820
30838
  const postYear = getPacificYear(data.date);
30821
30839
  const post = {
@@ -30877,11 +30895,11 @@ async function parseMarkdownFile(filePath) {
30877
30895
  }
30878
30896
 
30879
30897
  // src/parser.ts
30880
- async function parseMarkdownDirectory(contentDir, strictMode = false) {
30898
+ async function parseMarkdownDirectory(contentDir, strictMode = false, cdnConfig) {
30881
30899
  try {
30882
30900
  const markdownFiles = await findFilesByPattern("**/*.md", contentDir, true);
30883
30901
  console.log(`Found ${markdownFiles.length} markdown files`);
30884
- const resultsPromises = markdownFiles.map((filePath) => parseMarkdownFile(filePath));
30902
+ const resultsPromises = markdownFiles.map((filePath) => parseMarkdownFile(filePath, cdnConfig));
30885
30903
  const results = await Promise.all(resultsPromises);
30886
30904
  const posts = [];
30887
30905
  const errors = [];
@@ -31558,7 +31576,7 @@ class SiteGenerator {
31558
31576
  }
31559
31577
  }
31560
31578
  const strictMode = this.options.config.strictMode ?? false;
31561
- const posts = await parseMarkdownDirectory(this.options.contentDir, strictMode);
31579
+ const posts = await parseMarkdownDirectory(this.options.contentDir, strictMode, this.options.config.cdn);
31562
31580
  const tags = {};
31563
31581
  posts.forEach((post) => {
31564
31582
  post.tagSlugs = {};
@@ -32317,7 +32335,7 @@ function createUploader(config) {
32317
32335
  }
32318
32336
 
32319
32337
  // src/utils/image-uploader.ts
32320
- var DEFAULT_IMAGES_DIR = path7.join(process.cwd(), "images");
32338
+ var DEFAULT_IMAGES_DIR = path7.join(process.cwd(), "assets");
32321
32339
  async function uploadImages(options2 = {}) {
32322
32340
  try {
32323
32341
  const imagesDir = path7.resolve(options2.images || DEFAULT_IMAGES_DIR);
package/dist/parser.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { Post } from "./types";
1
+ import { Post, CDNConfig } from "./types";
2
2
  import { type ParseError } from "./utils/markdown-utils";
3
3
  export interface ParseResult {
4
4
  posts: Post[];
5
5
  errors: ParseError[];
6
6
  }
7
- export declare function parseMarkdownDirectory(contentDir: string, strictMode?: boolean): Promise<Post[]>;
7
+ export declare function parseMarkdownDirectory(contentDir: string, strictMode?: boolean, cdnConfig?: CDNConfig): Promise<Post[]>;
package/dist/types.d.ts CHANGED
@@ -80,6 +80,17 @@ export interface CSSConfig {
80
80
  /** Whether to watch for changes in development */
81
81
  watch?: boolean;
82
82
  }
83
+ /**
84
+ * Configuration for CDN URL transformation
85
+ */
86
+ export interface CDNConfig {
87
+ /** Base URL for CDN (e.g., "https://img.beconfused.com") */
88
+ baseUrl: string;
89
+ /** Path pattern for CDN URLs (e.g., "{year}/{slug}/{filename}") */
90
+ pathPattern: string;
91
+ /** Whether CDN transformation is enabled */
92
+ enabled: boolean;
93
+ }
83
94
  /**
84
95
  * Configuration for the site
85
96
  */
@@ -98,6 +109,8 @@ export interface SiteConfig {
98
109
  s3?: S3Config;
99
110
  /** CSS processing configuration */
100
111
  css?: CSSConfig;
112
+ /** CDN URL transformation configuration */
113
+ cdn?: CDNConfig;
101
114
  /** Optional number of tags to display on homepage (sorted by count). If not set, all tags are shown */
102
115
  maxTagsOnHomepage?: number;
103
116
  /** Optional list of domains to exclude from nofollow attribute. Links to these domains will have follow attribute. */
@@ -1,7 +1,7 @@
1
- import { Post } from "../types";
1
+ import { Post, CDNConfig } from "../types";
2
2
  export declare function setNoFollowExceptions(exceptions: string[]): void;
3
3
  export declare function extractExcerpt(content: string, maxLength?: number): string;
4
- export declare function convertMarkdownToHtml(markdownContent: string): string;
4
+ export declare function convertMarkdownToHtml(markdownContent: string, cdnConfig?: CDNConfig): string;
5
5
  export interface ParseError {
6
6
  file: string;
7
7
  type: "yaml" | "missing_field" | "file_not_found" | "unknown" | "validation";
@@ -12,4 +12,4 @@ export interface ParseMarkdownResult {
12
12
  post: Post | null;
13
13
  error: ParseError | null;
14
14
  }
15
- export declare function parseMarkdownFile(filePath: string): Promise<ParseMarkdownResult>;
15
+ export declare function parseMarkdownFile(filePath: string, cdnConfig?: CDNConfig): Promise<ParseMarkdownResult>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bunki",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
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",