bunki 0.17.1 → 0.18.1

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
@@ -21506,7 +21506,7 @@ var require_picocolors = __commonJS((exports, module) => {
21506
21506
  module.exports.createColors = createColors;
21507
21507
  });
21508
21508
 
21509
- // node_modules/sanitize-html/node_modules/postcss/lib/tokenize.js
21509
+ // node_modules/postcss/lib/tokenize.js
21510
21510
  var require_tokenize = __commonJS((exports, module) => {
21511
21511
  var SINGLE_QUOTE = 39;
21512
21512
  var DOUBLE_QUOTE = 34;
@@ -21720,7 +21720,7 @@ var require_tokenize = __commonJS((exports, module) => {
21720
21720
  };
21721
21721
  });
21722
21722
 
21723
- // node_modules/sanitize-html/node_modules/postcss/lib/terminal-highlight.js
21723
+ // node_modules/postcss/lib/terminal-highlight.js
21724
21724
  var require_terminal_highlight = __commonJS((exports, module) => {
21725
21725
  var pico = require_picocolors();
21726
21726
  var tokenizer = require_tokenize();
@@ -21781,7 +21781,7 @@ var require_terminal_highlight = __commonJS((exports, module) => {
21781
21781
  module.exports = terminalHighlight;
21782
21782
  });
21783
21783
 
21784
- // node_modules/sanitize-html/node_modules/postcss/lib/css-syntax-error.js
21784
+ // node_modules/postcss/lib/css-syntax-error.js
21785
21785
  var require_css_syntax_error = __commonJS((exports, module) => {
21786
21786
  var pico = require_picocolors();
21787
21787
  var terminalHighlight = require_terminal_highlight();
@@ -21881,7 +21881,7 @@ var require_css_syntax_error = __commonJS((exports, module) => {
21881
21881
  CssSyntaxError.default = CssSyntaxError;
21882
21882
  });
21883
21883
 
21884
- // node_modules/sanitize-html/node_modules/postcss/lib/stringifier.js
21884
+ // node_modules/postcss/lib/stringifier.js
21885
21885
  var require_stringifier = __commonJS((exports, module) => {
21886
21886
  var DEFAULT_RAW = {
21887
21887
  after: `
@@ -22210,7 +22210,7 @@ var require_stringifier = __commonJS((exports, module) => {
22210
22210
  Stringifier.default = Stringifier;
22211
22211
  });
22212
22212
 
22213
- // node_modules/sanitize-html/node_modules/postcss/lib/stringify.js
22213
+ // node_modules/postcss/lib/stringify.js
22214
22214
  var require_stringify4 = __commonJS((exports, module) => {
22215
22215
  var Stringifier = require_stringifier();
22216
22216
  function stringify(node, builder) {
@@ -22221,13 +22221,13 @@ var require_stringify4 = __commonJS((exports, module) => {
22221
22221
  stringify.default = stringify;
22222
22222
  });
22223
22223
 
22224
- // node_modules/sanitize-html/node_modules/postcss/lib/symbols.js
22224
+ // node_modules/postcss/lib/symbols.js
22225
22225
  var require_symbols = __commonJS((exports, module) => {
22226
22226
  exports.isClean = Symbol("isClean");
22227
22227
  exports.my = Symbol("my");
22228
22228
  });
22229
22229
 
22230
- // node_modules/sanitize-html/node_modules/postcss/lib/node.js
22230
+ // node_modules/postcss/lib/node.js
22231
22231
  var require_node2 = __commonJS((exports, module) => {
22232
22232
  var CssSyntaxError = require_css_syntax_error();
22233
22233
  var Stringifier = require_stringifier();
@@ -22396,7 +22396,7 @@ var require_node2 = __commonJS((exports, module) => {
22396
22396
  let index = this.parent.index(this);
22397
22397
  return this.parent.nodes[index + 1];
22398
22398
  }
22399
- positionBy(opts) {
22399
+ positionBy(opts = {}) {
22400
22400
  let pos = this.source.start;
22401
22401
  if (opts.index) {
22402
22402
  pos = this.positionInside(opts.index);
@@ -22424,7 +22424,7 @@ var require_node2 = __commonJS((exports, module) => {
22424
22424
  column += 1;
22425
22425
  }
22426
22426
  }
22427
- return { column, line };
22427
+ return { column, line, offset: end };
22428
22428
  }
22429
22429
  prev() {
22430
22430
  if (!this.parent)
@@ -22432,20 +22432,23 @@ var require_node2 = __commonJS((exports, module) => {
22432
22432
  let index = this.parent.index(this);
22433
22433
  return this.parent.nodes[index - 1];
22434
22434
  }
22435
- rangeBy(opts) {
22435
+ rangeBy(opts = {}) {
22436
+ let inputString = "document" in this.source.input ? this.source.input.document : this.source.input.css;
22436
22437
  let start = {
22437
22438
  column: this.source.start.column,
22438
- line: this.source.start.line
22439
+ line: this.source.start.line,
22440
+ offset: sourceOffset(inputString, this.source.start)
22439
22441
  };
22440
22442
  let end = this.source.end ? {
22441
22443
  column: this.source.end.column + 1,
22442
- line: this.source.end.line
22444
+ line: this.source.end.line,
22445
+ offset: typeof this.source.end.offset === "number" ? this.source.end.offset : sourceOffset(inputString, this.source.end) + 1
22443
22446
  } : {
22444
22447
  column: start.column + 1,
22445
- line: start.line
22448
+ line: start.line,
22449
+ offset: start.offset + 1
22446
22450
  };
22447
22451
  if (opts.word) {
22448
- let inputString = "document" in this.source.input ? this.source.input.document : this.source.input.css;
22449
22452
  let stringRepresentation = inputString.slice(sourceOffset(inputString, this.source.start), sourceOffset(inputString, this.source.end));
22450
22453
  let index = stringRepresentation.indexOf(opts.word);
22451
22454
  if (index !== -1) {
@@ -22456,7 +22459,8 @@ var require_node2 = __commonJS((exports, module) => {
22456
22459
  if (opts.start) {
22457
22460
  start = {
22458
22461
  column: opts.start.column,
22459
- line: opts.start.line
22462
+ line: opts.start.line,
22463
+ offset: sourceOffset(inputString, opts.start)
22460
22464
  };
22461
22465
  } else if (opts.index) {
22462
22466
  start = this.positionInside(opts.index);
@@ -22464,7 +22468,8 @@ var require_node2 = __commonJS((exports, module) => {
22464
22468
  if (opts.end) {
22465
22469
  end = {
22466
22470
  column: opts.end.column,
22467
- line: opts.end.line
22471
+ line: opts.end.line,
22472
+ offset: sourceOffset(inputString, opts.end)
22468
22473
  };
22469
22474
  } else if (typeof opts.endIndex === "number") {
22470
22475
  end = this.positionInside(opts.endIndex);
@@ -22473,7 +22478,11 @@ var require_node2 = __commonJS((exports, module) => {
22473
22478
  }
22474
22479
  }
22475
22480
  if (end.line < start.line || end.line === start.line && end.column <= start.column) {
22476
- end = { column: start.column + 1, line: start.line };
22481
+ end = {
22482
+ column: start.column + 1,
22483
+ line: start.line,
22484
+ offset: start.offset + 1
22485
+ };
22477
22486
  }
22478
22487
  return { end, start };
22479
22488
  }
@@ -22538,6 +22547,8 @@ var require_node2 = __commonJS((exports, module) => {
22538
22547
  } else if (typeof value === "object" && value.toJSON) {
22539
22548
  fixed[name] = value.toJSON(null, inputs);
22540
22549
  } else if (name === "source") {
22550
+ if (value == null)
22551
+ continue;
22541
22552
  let inputId = inputs.get(value.input);
22542
22553
  if (inputId == null) {
22543
22554
  inputId = inputsNextIndex;
@@ -22573,7 +22584,7 @@ var require_node2 = __commonJS((exports, module) => {
22573
22584
  });
22574
22585
  return result;
22575
22586
  }
22576
- warn(result, text, opts) {
22587
+ warn(result, text, opts = {}) {
22577
22588
  let data = { node: this };
22578
22589
  for (let i in opts)
22579
22590
  data[i] = opts[i];
@@ -22584,7 +22595,7 @@ var require_node2 = __commonJS((exports, module) => {
22584
22595
  Node.default = Node;
22585
22596
  });
22586
22597
 
22587
- // node_modules/sanitize-html/node_modules/postcss/lib/comment.js
22598
+ // node_modules/postcss/lib/comment.js
22588
22599
  var require_comment = __commonJS((exports, module) => {
22589
22600
  var Node = require_node2();
22590
22601
 
@@ -22598,7 +22609,7 @@ var require_comment = __commonJS((exports, module) => {
22598
22609
  Comment.default = Comment;
22599
22610
  });
22600
22611
 
22601
- // node_modules/sanitize-html/node_modules/postcss/lib/declaration.js
22612
+ // node_modules/postcss/lib/declaration.js
22602
22613
  var require_declaration = __commonJS((exports, module) => {
22603
22614
  var Node = require_node2();
22604
22615
 
@@ -22618,7 +22629,7 @@ var require_declaration = __commonJS((exports, module) => {
22618
22629
  Declaration.default = Declaration;
22619
22630
  });
22620
22631
 
22621
- // node_modules/sanitize-html/node_modules/postcss/lib/container.js
22632
+ // node_modules/postcss/lib/container.js
22622
22633
  var require_container = __commonJS((exports, module) => {
22623
22634
  var Comment = require_comment();
22624
22635
  var Declaration = require_declaration();
@@ -23017,7 +23028,7 @@ var require_container = __commonJS((exports, module) => {
23017
23028
  };
23018
23029
  });
23019
23030
 
23020
- // node_modules/sanitize-html/node_modules/postcss/lib/at-rule.js
23031
+ // node_modules/postcss/lib/at-rule.js
23021
23032
  var require_at_rule = __commonJS((exports, module) => {
23022
23033
  var Container = require_container();
23023
23034
 
@@ -23042,7 +23053,7 @@ var require_at_rule = __commonJS((exports, module) => {
23042
23053
  Container.registerAtRule(AtRule);
23043
23054
  });
23044
23055
 
23045
- // node_modules/sanitize-html/node_modules/postcss/lib/document.js
23056
+ // node_modules/postcss/lib/document.js
23046
23057
  var require_document = __commonJS((exports, module) => {
23047
23058
  var Container = require_container();
23048
23059
  var LazyResult;
@@ -24927,7 +24938,7 @@ var require_source_map = __commonJS((exports) => {
24927
24938
  exports.SourceNode = require_source_node().SourceNode;
24928
24939
  });
24929
24940
 
24930
- // node_modules/sanitize-html/node_modules/postcss/lib/previous-map.js
24941
+ // node_modules/postcss/lib/previous-map.js
24931
24942
  var require_previous_map = __commonJS((exports, module) => {
24932
24943
  var { existsSync, readFileSync } = __require("fs");
24933
24944
  var { dirname, join } = __require("path");
@@ -25049,7 +25060,7 @@ var require_previous_map = __commonJS((exports, module) => {
25049
25060
  PreviousMap.default = PreviousMap;
25050
25061
  });
25051
25062
 
25052
- // node_modules/sanitize-html/node_modules/postcss/lib/input.js
25063
+ // node_modules/postcss/lib/input.js
25053
25064
  var require_input = __commonJS((exports, module) => {
25054
25065
  var { nanoid } = require_non_secure();
25055
25066
  var { isAbsolute, resolve } = __require("path");
@@ -25058,9 +25069,23 @@ var require_input = __commonJS((exports, module) => {
25058
25069
  var CssSyntaxError = require_css_syntax_error();
25059
25070
  var PreviousMap = require_previous_map();
25060
25071
  var terminalHighlight = require_terminal_highlight();
25061
- var fromOffsetCache = Symbol("fromOffsetCache");
25072
+ var lineToIndexCache = Symbol("lineToIndexCache");
25062
25073
  var sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator);
25063
25074
  var pathAvailable = Boolean(resolve && isAbsolute);
25075
+ function getLineToIndex(input) {
25076
+ if (input[lineToIndexCache])
25077
+ return input[lineToIndexCache];
25078
+ let lines = input.css.split(`
25079
+ `);
25080
+ let lineToIndex = new Array(lines.length);
25081
+ let prevIndex = 0;
25082
+ for (let i = 0, l = lines.length;i < l; i++) {
25083
+ lineToIndex[i] = prevIndex;
25084
+ prevIndex += lines[i].length + 1;
25085
+ }
25086
+ input[lineToIndexCache] = lineToIndex;
25087
+ return lineToIndex;
25088
+ }
25064
25089
 
25065
25090
  class Input {
25066
25091
  get from() {
@@ -25103,30 +25128,37 @@ var require_input = __commonJS((exports, module) => {
25103
25128
  this.map.file = this.from;
25104
25129
  }
25105
25130
  error(message, line, column, opts = {}) {
25106
- let endColumn, endLine, result;
25131
+ let endColumn, endLine, endOffset, offset, result;
25107
25132
  if (line && typeof line === "object") {
25108
25133
  let start = line;
25109
25134
  let end = column;
25110
25135
  if (typeof start.offset === "number") {
25111
- let pos = this.fromOffset(start.offset);
25136
+ offset = start.offset;
25137
+ let pos = this.fromOffset(offset);
25112
25138
  line = pos.line;
25113
25139
  column = pos.col;
25114
25140
  } else {
25115
25141
  line = start.line;
25116
25142
  column = start.column;
25143
+ offset = this.fromLineAndColumn(line, column);
25117
25144
  }
25118
25145
  if (typeof end.offset === "number") {
25119
- let pos = this.fromOffset(end.offset);
25146
+ endOffset = end.offset;
25147
+ let pos = this.fromOffset(endOffset);
25120
25148
  endLine = pos.line;
25121
25149
  endColumn = pos.col;
25122
25150
  } else {
25123
25151
  endLine = end.line;
25124
25152
  endColumn = end.column;
25153
+ endOffset = this.fromLineAndColumn(end.line, end.column);
25125
25154
  }
25126
25155
  } else if (!column) {
25127
- let pos = this.fromOffset(line);
25156
+ offset = line;
25157
+ let pos = this.fromOffset(offset);
25128
25158
  line = pos.line;
25129
25159
  column = pos.col;
25160
+ } else {
25161
+ offset = this.fromLineAndColumn(line, column);
25130
25162
  }
25131
25163
  let origin = this.origin(line, column, endLine, endColumn);
25132
25164
  if (origin) {
@@ -25134,7 +25166,7 @@ var require_input = __commonJS((exports, module) => {
25134
25166
  } else {
25135
25167
  result = new CssSyntaxError(message, endLine === undefined ? line : { column, line }, endLine === undefined ? column : { column: endColumn, line: endLine }, this.css, this.file, opts.plugin);
25136
25168
  }
25137
- result.input = { column, endColumn, endLine, line, source: this.css };
25169
+ result.input = { column, endColumn, endLine, endOffset, line, offset, source: this.css };
25138
25170
  if (this.file) {
25139
25171
  if (pathToFileURL) {
25140
25172
  result.input.url = pathToFileURL(this.file).toString();
@@ -25143,22 +25175,14 @@ var require_input = __commonJS((exports, module) => {
25143
25175
  }
25144
25176
  return result;
25145
25177
  }
25178
+ fromLineAndColumn(line, column) {
25179
+ let lineToIndex = getLineToIndex(this);
25180
+ let index = lineToIndex[line - 1];
25181
+ return index + column - 1;
25182
+ }
25146
25183
  fromOffset(offset) {
25147
- let lastLine, lineToIndex;
25148
- if (!this[fromOffsetCache]) {
25149
- let lines = this.css.split(`
25150
- `);
25151
- lineToIndex = new Array(lines.length);
25152
- let prevIndex = 0;
25153
- for (let i = 0, l = lines.length;i < l; i++) {
25154
- lineToIndex[i] = prevIndex;
25155
- prevIndex += lines[i].length + 1;
25156
- }
25157
- this[fromOffsetCache] = lineToIndex;
25158
- } else {
25159
- lineToIndex = this[fromOffsetCache];
25160
- }
25161
- lastLine = lineToIndex[lineToIndex.length - 1];
25184
+ let lineToIndex = getLineToIndex(this);
25185
+ let lastLine = lineToIndex[lineToIndex.length - 1];
25162
25186
  let min = 0;
25163
25187
  if (offset >= lastLine) {
25164
25188
  min = lineToIndex.length - 1;
@@ -25247,7 +25271,7 @@ var require_input = __commonJS((exports, module) => {
25247
25271
  }
25248
25272
  });
25249
25273
 
25250
- // node_modules/sanitize-html/node_modules/postcss/lib/root.js
25274
+ // node_modules/postcss/lib/root.js
25251
25275
  var require_root = __commonJS((exports, module) => {
25252
25276
  var Container = require_container();
25253
25277
  var LazyResult;
@@ -25300,7 +25324,7 @@ var require_root = __commonJS((exports, module) => {
25300
25324
  Container.registerRoot(Root);
25301
25325
  });
25302
25326
 
25303
- // node_modules/sanitize-html/node_modules/postcss/lib/list.js
25327
+ // node_modules/postcss/lib/list.js
25304
25328
  var require_list = __commonJS((exports, module) => {
25305
25329
  var list = {
25306
25330
  comma(string) {
@@ -25358,7 +25382,7 @@ var require_list = __commonJS((exports, module) => {
25358
25382
  list.default = list;
25359
25383
  });
25360
25384
 
25361
- // node_modules/sanitize-html/node_modules/postcss/lib/rule.js
25385
+ // node_modules/postcss/lib/rule.js
25362
25386
  var require_rule = __commonJS((exports, module) => {
25363
25387
  var Container = require_container();
25364
25388
  var list = require_list();
@@ -25384,7 +25408,7 @@ var require_rule = __commonJS((exports, module) => {
25384
25408
  Container.registerRule(Rule);
25385
25409
  });
25386
25410
 
25387
- // node_modules/sanitize-html/node_modules/postcss/lib/fromJSON.js
25411
+ // node_modules/postcss/lib/fromJSON.js
25388
25412
  var require_fromJSON = __commonJS((exports, module) => {
25389
25413
  var AtRule = require_at_rule();
25390
25414
  var Comment = require_comment();
@@ -25438,7 +25462,7 @@ var require_fromJSON = __commonJS((exports, module) => {
25438
25462
  fromJSON.default = fromJSON;
25439
25463
  });
25440
25464
 
25441
- // node_modules/sanitize-html/node_modules/postcss/lib/map-generator.js
25465
+ // node_modules/postcss/lib/map-generator.js
25442
25466
  var require_map_generator = __commonJS((exports, module) => {
25443
25467
  var { dirname, relative, resolve, sep } = __require("path");
25444
25468
  var { SourceMapConsumer, SourceMapGenerator } = require_source_map();
@@ -25768,7 +25792,7 @@ var require_map_generator = __commonJS((exports, module) => {
25768
25792
  module.exports = MapGenerator;
25769
25793
  });
25770
25794
 
25771
- // node_modules/sanitize-html/node_modules/postcss/lib/parser.js
25795
+ // node_modules/postcss/lib/parser.js
25772
25796
  var require_parser2 = __commonJS((exports, module) => {
25773
25797
  var AtRule = require_at_rule();
25774
25798
  var Comment = require_comment();
@@ -26289,7 +26313,7 @@ var require_parser2 = __commonJS((exports, module) => {
26289
26313
  module.exports = Parser;
26290
26314
  });
26291
26315
 
26292
- // node_modules/sanitize-html/node_modules/postcss/lib/parse.js
26316
+ // node_modules/postcss/lib/parse.js
26293
26317
  var require_parse4 = __commonJS((exports, module) => {
26294
26318
  var Container = require_container();
26295
26319
  var Input = require_input();
@@ -26323,7 +26347,7 @@ You tried to parse Less with ` + "the standard CSS parser; " + "try again with t
26323
26347
  Container.registerParse(parse2);
26324
26348
  });
26325
26349
 
26326
- // node_modules/sanitize-html/node_modules/postcss/lib/warning.js
26350
+ // node_modules/postcss/lib/warning.js
26327
26351
  var require_warning = __commonJS((exports, module) => {
26328
26352
  class Warning {
26329
26353
  constructor(text, opts = {}) {
@@ -26357,7 +26381,7 @@ var require_warning = __commonJS((exports, module) => {
26357
26381
  Warning.default = Warning;
26358
26382
  });
26359
26383
 
26360
- // node_modules/sanitize-html/node_modules/postcss/lib/result.js
26384
+ // node_modules/postcss/lib/result.js
26361
26385
  var require_result = __commonJS((exports, module) => {
26362
26386
  var Warning = require_warning();
26363
26387
 
@@ -26370,7 +26394,7 @@ var require_result = __commonJS((exports, module) => {
26370
26394
  this.messages = [];
26371
26395
  this.root = root;
26372
26396
  this.opts = opts;
26373
- this.css = undefined;
26397
+ this.css = "";
26374
26398
  this.map = undefined;
26375
26399
  }
26376
26400
  toString() {
@@ -26394,7 +26418,7 @@ var require_result = __commonJS((exports, module) => {
26394
26418
  Result.default = Result;
26395
26419
  });
26396
26420
 
26397
- // node_modules/sanitize-html/node_modules/postcss/lib/warn-once.js
26421
+ // node_modules/postcss/lib/warn-once.js
26398
26422
  var require_warn_once = __commonJS((exports, module) => {
26399
26423
  var printed = {};
26400
26424
  module.exports = function warnOnce(message) {
@@ -26407,7 +26431,7 @@ var require_warn_once = __commonJS((exports, module) => {
26407
26431
  };
26408
26432
  });
26409
26433
 
26410
- // node_modules/sanitize-html/node_modules/postcss/lib/lazy-result.js
26434
+ // node_modules/postcss/lib/lazy-result.js
26411
26435
  var require_lazy_result = __commonJS((exports, module) => {
26412
26436
  var Container = require_container();
26413
26437
  var Document = require_document();
@@ -26885,7 +26909,7 @@ var require_lazy_result = __commonJS((exports, module) => {
26885
26909
  Document.registerLazyResult(LazyResult);
26886
26910
  });
26887
26911
 
26888
- // node_modules/sanitize-html/node_modules/postcss/lib/no-work-result.js
26912
+ // node_modules/postcss/lib/no-work-result.js
26889
26913
  var require_no_work_result = __commonJS((exports, module) => {
26890
26914
  var MapGenerator = require_map_generator();
26891
26915
  var parse2 = require_parse4();
@@ -26999,7 +27023,7 @@ var require_no_work_result = __commonJS((exports, module) => {
26999
27023
  NoWorkResult.default = NoWorkResult;
27000
27024
  });
27001
27025
 
27002
- // node_modules/sanitize-html/node_modules/postcss/lib/processor.js
27026
+ // node_modules/postcss/lib/processor.js
27003
27027
  var require_processor = __commonJS((exports, module) => {
27004
27028
  var Document = require_document();
27005
27029
  var LazyResult = require_lazy_result();
@@ -27008,7 +27032,7 @@ var require_processor = __commonJS((exports, module) => {
27008
27032
 
27009
27033
  class Processor {
27010
27034
  constructor(plugins = []) {
27011
- this.version = "8.5.3";
27035
+ this.version = "8.5.6";
27012
27036
  this.plugins = this.normalize(plugins);
27013
27037
  }
27014
27038
  normalize(plugins) {
@@ -27053,7 +27077,7 @@ var require_processor = __commonJS((exports, module) => {
27053
27077
  Document.registerProcessor(Processor);
27054
27078
  });
27055
27079
 
27056
- // node_modules/sanitize-html/node_modules/postcss/lib/postcss.js
27080
+ // node_modules/postcss/lib/postcss.js
27057
27081
  var require_postcss = __commonJS((exports, module) => {
27058
27082
  var AtRule = require_at_rule();
27059
27083
  var Comment = require_comment();
@@ -27672,6 +27696,15 @@ and ensure you are accounting for this risk.
27672
27696
  }, options2.parser);
27673
27697
  parser.write(html);
27674
27698
  parser.end();
27699
+ if (options2.disallowedTagsMode === "escape" || options2.disallowedTagsMode === "recursiveEscape") {
27700
+ const lastParsedIndex = parser.endIndex;
27701
+ if (lastParsedIndex != null && lastParsedIndex >= 0 && lastParsedIndex < html.length) {
27702
+ const unparsed = html.substring(lastParsedIndex);
27703
+ result += escapeHtml(unparsed);
27704
+ } else if ((lastParsedIndex == null || lastParsedIndex < 0) && html.length > 0 && result === "") {
27705
+ result = escapeHtml(html);
27706
+ }
27707
+ }
27675
27708
  return result;
27676
27709
  function initializeState() {
27677
27710
  result = "";
@@ -32320,7 +32353,7 @@ ${e}</tr>
32320
32353
  if (i === null)
32321
32354
  return O(n);
32322
32355
  e = i;
32323
- let s = `<img src="${e}" alt="${n}"`;
32356
+ let s = `<img src="${e}" alt="${O(n)}"`;
32324
32357
  return t && (s += ` title="${O(t)}"`), s += ">", s;
32325
32358
  }
32326
32359
  text(e) {
@@ -33538,9 +33571,8 @@ function generateBlogPostingSchema(options2) {
33538
33571
  if (post.tags && post.tags.length > 0) {
33539
33572
  blogPosting.articleSection = post.tags[0];
33540
33573
  }
33541
- if (post.content) {
33542
- const wordCount = post.content.split(/\s+/).length;
33543
- blogPosting.wordCount = wordCount;
33574
+ if (post.wordCount) {
33575
+ blogPosting.wordCount = post.wordCount;
33544
33576
  }
33545
33577
  blogPosting.inLanguage = site.rssLanguage || "en-US";
33546
33578
  return blogPosting;
@@ -33899,11 +33931,6 @@ function getTotalPages(totalItems, pageSize) {
33899
33931
  }
33900
33932
 
33901
33933
  // src/generators/feeds.ts
33902
- function extractFirstImageUrl2(html) {
33903
- const imgRegex = /<img[^>]+src=["']([^"']+)["']/;
33904
- const match = html.match(imgRegex);
33905
- return match ? match[1] : null;
33906
- }
33907
33934
  function makeAbsoluteUrl(imageUrl, baseUrl) {
33908
33935
  return imageUrl.startsWith("http") ? imageUrl : `${baseUrl}${imageUrl}`;
33909
33936
  }
@@ -33918,8 +33945,7 @@ function generateRSSFeed(site, config) {
33918
33945
  const rssItems = posts.map((post) => {
33919
33946
  const postUrl = `${config.baseUrl}${post.url}`;
33920
33947
  const pubDate = formatRSSDate(post.date);
33921
- const featuredImage = extractFirstImageUrl2(post.html);
33922
- const absoluteImageUrl = featuredImage ? makeAbsoluteUrl(featuredImage, config.baseUrl) : null;
33948
+ const absoluteImageUrl = post.image ? makeAbsoluteUrl(post.image, config.baseUrl) : null;
33923
33949
  const author = config.authorEmail && config.authorName ? `${config.authorEmail} (${config.authorName})` : config.authorEmail || undefined;
33924
33950
  return buildRSSItem({
33925
33951
  title: post.title,
@@ -34083,18 +34109,10 @@ async function generatePostPages(site, config, outputDir) {
34083
34109
  const batch = site.posts.slice(i, i + batchSize);
34084
34110
  await Promise.all(batch.map(async (post) => {
34085
34111
  const postPath = post.url.substring(1);
34086
- const imageUrl = extractFirstImageUrl(post.html, config.baseUrl);
34087
- const schemas = generatePostPageSchemas({
34088
- post,
34089
- site: config,
34090
- imageUrl
34091
- });
34092
- const jsonLd = schemas.map((schema) => toScriptTag(schema)).join(`
34093
- `);
34094
34112
  const postHtml = import_nunjucks.default.render("post.njk", {
34095
34113
  site: config,
34096
34114
  post,
34097
- jsonLd
34115
+ jsonLd: post.jsonLd || ""
34098
34116
  });
34099
34117
  await writeHtmlFile(outputDir, `${postPath}index.html`, postHtml);
34100
34118
  }));
@@ -34387,8 +34405,7 @@ class SiteGenerator {
34387
34405
  this.metrics = new MetricsCollector;
34388
34406
  const env = import_nunjucks2.default.configure(this.options.templatesDir, {
34389
34407
  autoescape: true,
34390
- watch: false,
34391
- noCache: false
34408
+ watch: false
34392
34409
  });
34393
34410
  env.addFilter("date", (date, format) => {
34394
34411
  const d2 = toPacificTime(date);
@@ -34453,6 +34470,16 @@ class SiteGenerator {
34453
34470
  if (imageUrl) {
34454
34471
  post.image = imageUrl;
34455
34472
  }
34473
+ if (post.content) {
34474
+ post.wordCount = post.content.split(/\s+/).length;
34475
+ }
34476
+ const schemas = generatePostPageSchemas({
34477
+ post,
34478
+ site: this.options.config,
34479
+ imageUrl: post.image
34480
+ });
34481
+ post.jsonLd = schemas.map((schema) => toScriptTag(schema)).join(`
34482
+ `);
34456
34483
  post.tags.forEach((tagName) => {
34457
34484
  const tagSlug = import_slugify.default(tagName, { lower: true, strict: true });
34458
34485
  post.tagSlugs[tagName] = tagSlug;
@@ -34917,437 +34944,475 @@ function registerImagesPushCommand(program2) {
34917
34944
 
34918
34945
  // src/cli/commands/init.ts
34919
34946
  import path13 from "path";
34947
+ var defaultDependencies = {
34948
+ createDefaultConfig,
34949
+ ensureDir,
34950
+ writeFile: (filePath, data) => Bun.write(filePath, data),
34951
+ logger: console,
34952
+ exit: (code) => process.exit(code)
34953
+ };
34954
+ async function handleInitCommand(options2, deps = defaultDependencies) {
34955
+ try {
34956
+ const configPath = path13.resolve(options2.config);
34957
+ const configCreated = await deps.createDefaultConfig(configPath);
34958
+ if (!configCreated) {
34959
+ deps.logger.log(`
34960
+ Skipped initialization because the config file already exists`);
34961
+ return;
34962
+ }
34963
+ deps.logger.log("Creating directory structure...");
34964
+ const baseDir = process.cwd();
34965
+ const contentDir = path13.join(baseDir, "content");
34966
+ const templatesDir = path13.join(baseDir, "templates");
34967
+ const stylesDir = path13.join(templatesDir, "styles");
34968
+ const publicDir = path13.join(baseDir, "public");
34969
+ await deps.ensureDir(contentDir);
34970
+ await deps.ensureDir(templatesDir);
34971
+ await deps.ensureDir(stylesDir);
34972
+ await deps.ensureDir(publicDir);
34973
+ for (const [filename, content] of Object.entries(getDefaultTemplates())) {
34974
+ await deps.writeFile(path13.join(templatesDir, filename), content);
34975
+ }
34976
+ await deps.writeFile(path13.join(stylesDir, "main.css"), getDefaultCss());
34977
+ await deps.writeFile(path13.join(contentDir, "welcome.md"), getSamplePost());
34978
+ deps.logger.log(`
34979
+ Initialization complete! Here are the next steps:`);
34980
+ deps.logger.log("1. Edit bunki.config.ts to configure your site");
34981
+ deps.logger.log("2. Add markdown files to the content directory");
34982
+ deps.logger.log('3. Run "bunki generate" to build your site');
34983
+ deps.logger.log('4. Run "bunki serve" to preview your site locally');
34984
+ } catch (error) {
34985
+ deps.logger.error("Error initializing site:", error);
34986
+ deps.exit(1);
34987
+ }
34988
+ }
34989
+ function registerInitCommand(program2, deps = defaultDependencies) {
34990
+ return program2.command("init").description("Initialize a new site with default structure").option("-c, --config <file>", "Path to config file", "bunki.config.ts").action(async (options2) => {
34991
+ await handleInitCommand(options2, deps);
34992
+ });
34993
+ }
34994
+ function getDefaultTemplates() {
34995
+ return {
34996
+ "base.njk": String.raw`<!DOCTYPE html>
34997
+ <html lang="en">
34998
+ <head>
34999
+ <meta charset="UTF-8">
35000
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
35001
+ <title>{% block title %}{{ site.title }}{% endblock %}</title>
35002
+ <meta name="description" content="{% block description %}{{ site.description }}{% endblock %}">
35003
+ <link rel="stylesheet" href="/css/style.css">
35004
+ {% block head %}{% endblock %}
35005
+ </head>
35006
+ <body>
35007
+ <header>
35008
+ <div class="container">
35009
+ <h1><a href="/">{{ site.title }}</a></h1>
35010
+ <nav>
35011
+ <ul>
35012
+ <li><a href="/">Home</a></li>
35013
+ <li><a href="/tags/">Tags</a></li>
35014
+ </ul>
35015
+ </nav>
35016
+ </div>
35017
+ </header>
34920
35018
 
34921
- // src/cli/commands/templates/base-njk.ts
34922
- var baseNjk = String.raw`<!DOCTYPE html>
34923
- <html lang="en">
34924
- <head>
34925
- <meta charset="UTF-8">
34926
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
34927
- <title>{% block title %}{{ site.title }}{% endblock %}</title>
34928
- <meta name="description" content="{% block description %}{{ site.description }}{% endblock %}">
34929
- <link rel="stylesheet" href="/css/style.css">
34930
- {% block head %}{% endblock %}
34931
- </head>
34932
- <body>
34933
- <header>
34934
- <div class="container">
34935
- <h1><a href="/">{{ site.title }}</a></h1>
34936
- <nav>
34937
- <ul>
34938
- <li><a href="/">Home</a></li>
34939
- <li><a href="/tags/">Tags</a></li>
34940
- </ul>
34941
- </nav>
34942
- </div>
34943
- </header>
34944
-
34945
- <main class="container">
34946
- {% block content %}{% endblock %}
34947
- </main>
34948
-
34949
- <footer>
34950
- <div class="container">
34951
- <p>&copy; {{ "now" | date("YYYY") }} {{ site.title }}</p>
34952
- </div>
34953
- </footer>
34954
- </body>
34955
- </html>`;
34956
-
34957
- // src/cli/commands/templates/index-njk.ts
34958
- var indexNjk = String.raw`{% extends "base.njk" %}
34959
-
34960
- {% block content %}
34961
- <h1>Latest Posts</h1>
34962
-
34963
- {% if posts.length > 0 %}
34964
- <div class="posts">
34965
- {% for post in posts %}
34966
- <article class="post-card">
34967
- <h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
34968
- <div class="post-meta">
34969
- <time datetime="{{ post.date }}">{{ post.date | date("MMMM D, YYYY") }}</time>
34970
- {% if post.tags.length > 0 %}
34971
- <span class="tags">
34972
- {% for tag in post.tags %}
34973
- <a href="/tags/{{ post.tagSlugs[tag] }}/">{{ tag }}</a>{% if not loop.last %}, {% endif %}
34974
- {% endfor %}
34975
- </span>
34976
- {% endif %}
34977
- </div>
34978
- <div class="post-excerpt">{{ post.excerpt }}</div>
34979
- <a href="{{ post.url }}" class="read-more">Read more \u2192</a>
34980
- </article>
34981
- {% endfor %}
34982
- </div>
34983
-
34984
- {% if pagination.totalPages > 1 %}
34985
- <nav class="pagination">
34986
- {% if pagination.hasPrevPage %}
34987
- <a href="{{ pagination.pagePath }}{% if pagination.prevPage > 1 %}page/{{ pagination.prevPage }}/{% endif %}" class="prev">\u2190 Previous</a>
34988
- {% endif %}
34989
-
34990
- {% if pagination.hasNextPage %}
34991
- <a href="{{ pagination.pagePath }}page/{{ pagination.nextPage }}/" class="next">Next \u2192</a>
34992
- {% endif %}
34993
-
34994
- <span class="page-info">Page {{ pagination.currentPage }} of {{ pagination.totalPages }}</span>
34995
- </nav>
35019
+ <main class="container">
35020
+ {% block content %}{% endblock %}
35021
+ </main>
35022
+
35023
+ <footer>
35024
+ <div class="container">
35025
+ <p>&copy; {{ "now" | date("YYYY") }} {{ site.title }}</p>
35026
+ </div>
35027
+ </footer>
35028
+ </body>
35029
+ </html>`,
35030
+ "index.njk": String.raw`{% extends "base.njk" %}
35031
+
35032
+ {% block content %}
35033
+ <h1>Latest Posts</h1>
35034
+
35035
+ {% if posts.length > 0 %}
35036
+ <div class="posts">
35037
+ {% for post in posts %}
35038
+ <article class="post-card">
35039
+ <h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
35040
+ <div class="post-meta">
35041
+ <time datetime="{{ post.date }}">{{ post.date | date("MMMM D, YYYY") }}</time>
35042
+ {% if post.tags.length > 0 %}
35043
+ <span class="tags">
35044
+ {% for tag in post.tags %}
35045
+ <a href="/tags/{{ post.tagSlugs[tag] }}/">{{ tag }}</a>{% if not loop.last %}, {% endif %}
35046
+ {% endfor %}
35047
+ </span>
35048
+ {% endif %}
35049
+ </div>
35050
+ <div class="post-excerpt">{{ post.excerpt }}</div>
35051
+ <a href="{{ post.url }}" class="read-more">Read more \u2192</a>
35052
+ </article>
35053
+ {% endfor %}
35054
+ </div>
35055
+
35056
+ {% if pagination.totalPages > 1 %}
35057
+ <nav class="pagination">
35058
+ {% if pagination.hasPrevPage %}
35059
+ <a href="{{ pagination.pagePath }}{% if pagination.prevPage > 1 %}page/{{ pagination.prevPage }}/{% endif %}" class="prev">\u2190 Previous</a>
35060
+ {% endif %}
35061
+
35062
+ {% if pagination.hasNextPage %}
35063
+ <a href="{{ pagination.pagePath }}page/{{ pagination.nextPage }}/" class="next">Next \u2192</a>
35064
+ {% endif %}
35065
+
35066
+ <span class="page-info">Page {{ pagination.currentPage }} of {{ pagination.totalPages }}</span>
35067
+ </nav>
35068
+ {% endif %}
35069
+ {% else %}
35070
+ <p>No posts yet!</p>
34996
35071
  {% endif %}
34997
- {% else %}
34998
- <p>No posts yet!</p>
34999
- {% endif %}
35000
- {% endblock %}`;
35001
-
35002
- // src/cli/commands/templates/post-njk.ts
35003
- var postNjk = String.raw`{% extends "base.njk" %}
35004
-
35005
- {% block title %}{{ post.title }} | {{ site.title }}{% endblock %}
35006
- {% block description %}{{ post.excerpt }}{% endblock %}
35007
-
35008
- {% block content %}
35009
- <article class="post">
35010
- <header class="post-header">
35011
- <h1>{{ post.title }}</h1>
35012
- <div class="post-meta">
35013
- <time datetime="{{ post.date }}">{{ post.date | date("MMMM D, YYYY") }}</time>
35014
- {% if post.tags.length > 0 %}
35015
- <span class="tags">
35016
- {% for tag in post.tags %}
35017
- <a href="/tags/{{ post.tagSlugs[tag] }}/">{{ tag }}</a>{% if not loop.last %}, {% endif %}
35018
- {% endfor %}
35019
- </span>
35020
- {% endif %}
35072
+ {% endblock %}`,
35073
+ "post.njk": String.raw`{% extends "base.njk" %}
35074
+
35075
+ {% block title %}{{ post.title }} | {{ site.title }}{% endblock %}
35076
+ {% block description %}{{ post.excerpt }}{% endblock %}
35077
+
35078
+ {% block content %}
35079
+ <article class="post">
35080
+ <header class="post-header">
35081
+ <h1>{{ post.title }}</h1>
35082
+ <div class="post-meta">
35083
+ <time datetime="{{ post.date }}">{{ post.date | date("MMMM D, YYYY") }}</time>
35084
+ {% if post.tags.length > 0 %}
35085
+ <span class="tags">
35086
+ {% for tag in post.tags %}
35087
+ <a href="/tags/{{ post.tagSlugs[tag] }}/">{{ tag }}</a>{% if not loop.last %}, {% endif %}
35088
+ {% endfor %}
35089
+ </span>
35090
+ {% endif %}
35091
+ </div>
35092
+ </header>
35093
+
35094
+ <div class="post-content">
35095
+ {{ post.html | safe }}
35021
35096
  </div>
35022
- </header>
35097
+ </article>
35098
+ {% endblock %}`,
35099
+ "tag.njk": String.raw`{% extends "base.njk" %}
35100
+
35101
+ {% block title %}{{ tag.name }} | {{ site.title }}{% endblock %}
35102
+ {% block description %}Posts tagged with {{ tag.name }} on {{ site.title }}{% endblock %}
35103
+
35104
+ {% block content %}
35105
+ <h1>Posts tagged "{{ tag.name }}"</h1>
35023
35106
 
35024
- <div class="post-content">
35025
- {{ post.html | safe }}
35026
- </div>
35027
- </article>
35028
- {% endblock %}`;
35029
-
35030
- // src/cli/commands/templates/tag-njk.ts
35031
- var tagNjk = String.raw`{% extends "base.njk" %}
35032
-
35033
- {% block title %}{{ tag.name }} | {{ site.title }}{% endblock %}
35034
- {% block description %}Posts tagged with {{ tag.name }} on {{ site.title }}{% endblock %}
35035
-
35036
- {% block content %}
35037
- <h1>Posts tagged "{{ tag.name }}"</h1>
35038
-
35039
- {% if tag.description %}
35040
- <div class="tag-description">{{ tag.description }}</div>
35041
- {% endif %}
35042
-
35043
- {% if tag.posts.length > 0 %}
35044
- <div class="posts">
35045
- {% for post in tag.posts %}
35046
- <article class="post-card">
35047
- <h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
35048
- <div class="post-meta">
35049
- <time datetime="{{ post.date }}">{{ post.date | date("MMMM D, YYYY") }}</time>
35050
- </div>
35051
- <div class="post-excerpt">{{ post.excerpt }}</div>
35052
- <a href="{{ post.url }}" class="read-more">Read more \u2192</a>
35053
- </article>
35054
- {% endfor %}
35055
- </div>
35056
-
35057
- {% if pagination.totalPages > 1 %}
35058
- <nav class="pagination">
35059
- {% if pagination.hasPrevPage %}
35060
- <a href="{{ pagination.pagePath }}{% if pagination.prevPage > 1 %}page/{{ pagination.prevPage }}/{% endif %}" class="prev">\u2190 Previous</a>
35061
- {% endif %}
35062
-
35063
- {% if pagination.hasNextPage %}
35064
- <a href="{{ pagination.pagePath }}page/{{ pagination.nextPage }}/" class="next">Next \u2192</a>
35065
- {% endif %}
35066
-
35067
- <span class="page-info">Page {{ pagination.currentPage }} of {{ pagination.totalPages }}</span>
35068
- </nav>
35107
+ {% if tag.description %}
35108
+ <div class="tag-description">{{ tag.description }}</div>
35069
35109
  {% endif %}
35070
- {% else %}
35071
- <p>No posts with this tag yet!</p>
35072
- {% endif %}
35073
- {% endblock %}`;
35074
-
35075
- // src/cli/commands/templates/tags-njk.ts
35076
- var tagsNjk = String.raw`{% extends "base.njk" %}
35077
-
35078
- {% block title %}Tags | {{ site.title }}{% endblock %}
35079
- {% block description %}Browse all tags on {{ site.title }}{% endblock %}
35080
-
35081
- {% block content %}
35082
- <h1>All Tags</h1>
35083
-
35084
- {% if tags.length > 0 %}
35085
- <ul class="tags-list">
35086
- {% for tag in tags %}
35087
- <li>
35088
- <a href="/tags/{{ tag.slug }}/">{{ tag.name }}</a>
35089
- <span class="count">({{ tag.count }})</span>
35090
- {% if tag.description %}
35091
- <p class="description">{{ tag.description }}</p>
35110
+
35111
+ {% if tag.posts.length > 0 %}
35112
+ <div class="posts">
35113
+ {% for post in tag.posts %}
35114
+ <article class="post-card">
35115
+ <h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
35116
+ <div class="post-meta">
35117
+ <time datetime="{{ post.date }}">{{ post.date | date("MMMM D, YYYY") }}</time>
35118
+ </div>
35119
+ <div class="post-excerpt">{{ post.excerpt }}</div>
35120
+ <a href="{{ post.url }}" class="read-more">Read more \u2192</a>
35121
+ </article>
35122
+ {% endfor %}
35123
+ </div>
35124
+
35125
+ {% if pagination.totalPages > 1 %}
35126
+ <nav class="pagination">
35127
+ {% if pagination.hasPrevPage %}
35128
+ <a href="{{ pagination.pagePath }}{% if pagination.prevPage > 1 %}page/{{ pagination.prevPage }}/{% endif %}" class="prev">\u2190 Previous</a>
35092
35129
  {% endif %}
35093
- </li>
35094
- {% endfor %}
35095
- </ul>
35096
- {% else %}
35097
- <p>No tags found!</p>
35098
- {% endif %}
35099
- {% endblock %}`;
35100
-
35101
- // src/cli/commands/templates/archive-njk.ts
35102
- var archiveNjk = String.raw`{% extends "base.njk" %}
35103
-
35104
- {% block title %}Archive {{ year }} | {{ site.title }}{% endblock %}
35105
- {% block description %}Posts from {{ year }} on {{ site.title }}{% endblock %}
35106
-
35107
- {% block content %}
35108
- <h1>Posts from {{ year }}</h1>
35109
-
35110
- {% if posts.length > 0 %}
35111
- <div class="posts">
35112
- {% for post in posts %}
35113
- <article class="post-card">
35114
- <h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
35115
- <div class="post-meta">
35116
- <time datetime="{{ post.date }}">{{ post.date | date("MMMM D, YYYY") }}</time>
35117
- {% if post.tags.length > 0 %}
35118
- <span class="tags">
35119
- {% for tag in post.tags %}
35120
- <a href="/tags/{{ post.tagSlugs[tag] }}/">{{ tag }}</a>{% if not loop.last %}, {% endif %}
35121
- {% endfor %}
35122
- </span>
35130
+
35131
+ {% if pagination.hasNextPage %}
35132
+ <a href="{{ pagination.pagePath }}page/{{ pagination.nextPage }}/" class="next">Next \u2192</a>
35133
+ {% endif %}
35134
+
35135
+ <span class="page-info">Page {{ pagination.currentPage }} of {{ pagination.totalPages }}</span>
35136
+ </nav>
35137
+ {% endif %}
35138
+ {% else %}
35139
+ <p>No posts with this tag yet!</p>
35140
+ {% endif %}
35141
+ {% endblock %}`,
35142
+ "tags.njk": String.raw`{% extends "base.njk" %}
35143
+
35144
+ {% block title %}Tags | {{ site.title }}{% endblock %}
35145
+ {% block description %}Browse all tags on {{ site.title }}{% endblock %}
35146
+
35147
+ {% block content %}
35148
+ <h1>All Tags</h1>
35149
+
35150
+ {% if tags.length > 0 %}
35151
+ <ul class="tags-list">
35152
+ {% for tag in tags %}
35153
+ <li>
35154
+ <a href="/tags/{{ tag.slug }}/">{{ tag.name }}</a>
35155
+ <span class="count">({{ tag.count }})</span>
35156
+ {% if tag.description %}
35157
+ <p class="description">{{ tag.description }}</p>
35123
35158
  {% endif %}
35124
- </div>
35125
- <div class="post-excerpt">{{ post.excerpt }}</div>
35126
- <a href="{{ post.url }}" class="read-more">Read more \u2192</a>
35127
- </article>
35128
- {% endfor %}
35129
- </div>
35130
-
35131
- {% if pagination.totalPages > 1 %}
35132
- <nav class="pagination">
35133
- {% if pagination.hasPrevPage %}
35134
- <a href="/{{ year }}/{% if pagination.prevPage > 1 %}page/{{ pagination.prevPage }}/{% endif %}" class="prev">\u2190 Previous</a>
35135
- {% endif %}
35136
-
35137
- {% if pagination.hasNextPage %}
35138
- <a href="/{{ year }}/page/{{ pagination.nextPage }}/" class="next">Next \u2192</a>
35139
- {% endif %}
35140
-
35141
- <span class="page-info">Page {{ pagination.currentPage }} of {{ pagination.totalPages }}</span>
35142
- </nav>
35159
+ </li>
35160
+ {% endfor %}
35161
+ </ul>
35162
+ {% else %}
35163
+ <p>No tags found!</p>
35143
35164
  {% endif %}
35144
- {% else %}
35145
- <p>No posts from {{ year }}!</p>
35146
- {% endif %}
35147
- {% endblock %}`;
35148
-
35149
- // src/cli/commands/templates/default-css.ts
35150
- var defaultCss = String.raw`/* Reset & base styles */
35151
- * {
35152
- margin: 0;
35153
- padding: 0;
35154
- box-sizing: border-box;
35155
- }
35165
+ {% endblock %}`,
35166
+ "archive.njk": String.raw`{% extends "base.njk" %}
35167
+
35168
+ {% block title %}Archive {{ year }} | {{ site.title }}{% endblock %}
35169
+ {% block description %}Posts from {{ year }} on {{ site.title }}{% endblock %}
35170
+
35171
+ {% block content %}
35172
+ <h1>Posts from {{ year }}</h1>
35173
+
35174
+ {% if posts.length > 0 %}
35175
+ <div class="posts">
35176
+ {% for post in posts %}
35177
+ <article class="post-card">
35178
+ <h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
35179
+ <div class="post-meta">
35180
+ <time datetime="{{ post.date }}">{{ post.date | date("MMMM D, YYYY") }}</time>
35181
+ {% if post.tags.length > 0 %}
35182
+ <span class="tags">
35183
+ {% for tag in post.tags %}
35184
+ <a href="/tags/{{ post.tagSlugs[tag] }}/">{{ tag }}</a>{% if not loop.last %}, {% endif %}
35185
+ {% endfor %}
35186
+ </span>
35187
+ {% endif %}
35188
+ </div>
35189
+ <div class="post-excerpt">{{ post.excerpt }}</div>
35190
+ <a href="{{ post.url }}" class="read-more">Read more \u2192</a>
35191
+ </article>
35192
+ {% endfor %}
35193
+ </div>
35156
35194
 
35157
- body {
35158
- font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
35159
- line-height: 1.6;
35160
- color: #333;
35161
- background-color: #f8f9fa;
35162
- padding-bottom: 2rem;
35163
- }
35195
+ {% if pagination.totalPages > 1 %}
35196
+ <nav class="pagination">
35197
+ {% if pagination.hasPrevPage %}
35198
+ <a href="/{{ year }}/{% if pagination.prevPage > 1 %}page/{{ pagination.prevPage }}/{% endif %}" class="prev">\u2190 Previous</a>
35199
+ {% endif %}
35164
35200
 
35165
- a {
35166
- color: #0066cc;
35167
- text-decoration: none;
35168
- }
35201
+ {% if pagination.hasNextPage %}
35202
+ <a href="/{{ year }}/page/{{ pagination.nextPage }}/" class="next">Next \u2192</a>
35203
+ {% endif %}
35169
35204
 
35170
- a:hover {
35171
- text-decoration: underline;
35205
+ <span class="page-info">Page {{ pagination.currentPage }} of {{ pagination.totalPages }}</span>
35206
+ </nav>
35207
+ {% endif %}
35208
+ {% else %}
35209
+ <p>No posts from {{ year }}!</p>
35210
+ {% endif %}
35211
+ {% endblock %}`
35212
+ };
35172
35213
  }
35214
+ function getDefaultCss() {
35215
+ return String.raw`/* Reset & base styles */
35216
+ * {
35217
+ margin: 0;
35218
+ padding: 0;
35219
+ box-sizing: border-box;
35220
+ }
35173
35221
 
35174
- .container {
35175
- max-width: 800px;
35176
- margin: 0 auto;
35177
- padding: 0 1.5rem;
35178
- }
35222
+ body {
35223
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
35224
+ line-height: 1.6;
35225
+ color: #333;
35226
+ background-color: #f8f9fa;
35227
+ padding-bottom: 2rem;
35228
+ }
35179
35229
 
35180
- /* Header */
35181
- header {
35182
- background-color: #fff;
35183
- padding: 1.5rem 0;
35184
- box-shadow: 0 1px 3px rgba(0,0,0,0.1);
35185
- margin-bottom: 2rem;
35186
- }
35230
+ a {
35231
+ color: #0066cc;
35232
+ text-decoration: none;
35233
+ }
35187
35234
 
35188
- header h1 {
35189
- font-size: 1.8rem;
35190
- margin: 0;
35191
- }
35235
+ a:hover {
35236
+ text-decoration: underline;
35237
+ }
35192
35238
 
35193
- header h1 a {
35194
- color: #333;
35195
- text-decoration: none;
35196
- }
35239
+ .container {
35240
+ max-width: 800px;
35241
+ margin: 0 auto;
35242
+ padding: 0 1.5rem;
35243
+ }
35197
35244
 
35198
- header nav {
35199
- margin-top: 0.5rem;
35200
- }
35245
+ /* Header */
35246
+ header {
35247
+ background-color: #fff;
35248
+ padding: 1.5rem 0;
35249
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1);
35250
+ margin-bottom: 2rem;
35251
+ }
35201
35252
 
35202
- header nav ul {
35203
- display: flex;
35204
- list-style: none;
35205
- gap: 1.5rem;
35206
- }
35253
+ header h1 {
35254
+ font-size: 1.8rem;
35255
+ margin: 0;
35256
+ }
35207
35257
 
35208
- /* Main content */
35209
- main {
35210
- background-color: #fff;
35211
- padding: 2rem;
35212
- border-radius: 5px;
35213
- box-shadow: 0 1px 3px rgba(0,0,0,0.1);
35214
- }
35258
+ header h1 a {
35259
+ color: #333;
35260
+ text-decoration: none;
35261
+ }
35215
35262
 
35216
- /* Posts */
35217
- .posts {
35218
- display: flex;
35219
- flex-direction: column;
35220
- gap: 2rem;
35221
- }
35263
+ header nav {
35264
+ margin-top: 0.5rem;
35265
+ }
35222
35266
 
35223
- .post-card {
35224
- border-bottom: 1px solid #eee;
35225
- padding-bottom: 1.5rem;
35226
- }
35267
+ header nav ul {
35268
+ display: flex;
35269
+ list-style: none;
35270
+ gap: 1.5rem;
35271
+ }
35227
35272
 
35228
- .post-card:last-child {
35229
- border-bottom: none;
35230
- }
35273
+ /* Main content */
35274
+ main {
35275
+ background-color: #fff;
35276
+ padding: 2rem;
35277
+ border-radius: 5px;
35278
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1);
35279
+ }
35231
35280
 
35232
- .post-card h2 {
35233
- margin-bottom: 0.5rem;
35234
- }
35281
+ /* Posts */
35282
+ .posts {
35283
+ display: flex;
35284
+ flex-direction: column;
35285
+ gap: 2rem;
35286
+ }
35235
35287
 
35236
- .post-meta {
35237
- font-size: 0.9rem;
35238
- color: #6c757d;
35239
- margin-bottom: 1rem;
35240
- }
35288
+ .post-card {
35289
+ border-bottom: 1px solid #eee;
35290
+ padding-bottom: 1.5rem;
35291
+ }
35241
35292
 
35242
- .post-excerpt {
35243
- margin-bottom: 1rem;
35244
- }
35293
+ .post-card:last-child {
35294
+ border-bottom: none;
35295
+ }
35245
35296
 
35246
- .read-more {
35247
- font-weight: 500;
35248
- }
35297
+ .post-card h2 {
35298
+ margin-bottom: 0.5rem;
35299
+ }
35249
35300
 
35250
- /* Single post */
35251
- .post-header {
35252
- margin-bottom: 2rem;
35253
- }
35301
+ .post-meta {
35302
+ font-size: 0.9rem;
35303
+ color: #6c757d;
35304
+ margin-bottom: 1rem;
35305
+ }
35254
35306
 
35255
- .post-content {
35256
- line-height: 1.8;
35257
- }
35307
+ .post-excerpt {
35308
+ margin-bottom: 1rem;
35309
+ }
35258
35310
 
35259
- .post-content p,
35260
- .post-content ul,
35261
- .post-content ol,
35262
- .post-content blockquote {
35263
- margin-bottom: 1.5rem;
35264
- }
35311
+ .read-more {
35312
+ font-weight: 500;
35313
+ }
35265
35314
 
35266
- .post-content h2,
35267
- .post-content h3,
35268
- .post-content h4 {
35269
- margin-top: 2rem;
35270
- margin-bottom: 1rem;
35271
- }
35315
+ /* Single post */
35316
+ .post-header {
35317
+ margin-bottom: 2rem;
35318
+ }
35272
35319
 
35273
- .post-content img {
35274
- max-width: 100%;
35275
- height: auto;
35276
- display: block;
35277
- margin: 2rem auto;
35278
- }
35320
+ .post-content {
35321
+ line-height: 1.8;
35322
+ }
35279
35323
 
35280
- .post-content pre {
35281
- background-color: #f5f5f5;
35282
- padding: 1rem;
35283
- border-radius: 4px;
35284
- overflow-x: auto;
35285
- margin-bottom: 1.5rem;
35286
- }
35324
+ .post-content p,
35325
+ .post-content ul,
35326
+ .post-content ol,
35327
+ .post-content blockquote {
35328
+ margin-bottom: 1.5rem;
35329
+ }
35287
35330
 
35288
- .post-content code {
35289
- font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
35290
- font-size: 0.9em;
35291
- background-color: #f5f5f5;
35292
- padding: 0.2em 0.4em;
35293
- border-radius: 3px;
35294
- }
35331
+ .post-content h2,
35332
+ .post-content h3,
35333
+ .post-content h4 {
35334
+ margin-top: 2rem;
35335
+ margin-bottom: 1rem;
35336
+ }
35295
35337
 
35296
- .post-content pre code {
35297
- padding: 0;
35298
- background-color: transparent;
35299
- }
35338
+ .post-content img {
35339
+ max-width: 100%;
35340
+ height: auto;
35341
+ display: block;
35342
+ margin: 2rem auto;
35343
+ }
35300
35344
 
35301
- /* Tags */
35302
- .tags a {
35303
- display: inline-block;
35304
- margin-left: 0.5rem;
35305
- }
35345
+ .post-content pre {
35346
+ background-color: #f5f5f5;
35347
+ padding: 1rem;
35348
+ border-radius: 4px;
35349
+ overflow-x: auto;
35350
+ margin-bottom: 1.5rem;
35351
+ }
35306
35352
 
35307
- .tags-list {
35308
- list-style: none;
35309
- }
35353
+ .post-content code {
35354
+ font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
35355
+ font-size: 0.9em;
35356
+ background-color: #f5f5f5;
35357
+ padding: 0.2em 0.4em;
35358
+ border-radius: 3px;
35359
+ }
35310
35360
 
35311
- .tags-list li {
35312
- margin-bottom: 1rem;
35313
- }
35361
+ .post-content pre code {
35362
+ padding: 0;
35363
+ background-color: transparent;
35364
+ }
35314
35365
 
35315
- .tags-list .count {
35316
- color: #6c757d;
35317
- font-size: 0.9rem;
35318
- }
35366
+ /* Tags */
35367
+ .tags a {
35368
+ display: inline-block;
35369
+ margin-left: 0.5rem;
35370
+ }
35319
35371
 
35320
- .tags-list .description {
35321
- margin-top: 0.25rem;
35322
- font-size: 0.9rem;
35323
- color: #6c757d;
35324
- }
35372
+ .tags-list {
35373
+ list-style: none;
35374
+ }
35325
35375
 
35326
- /* Pagination */
35327
- .pagination {
35328
- display: flex;
35329
- justify-content: space-between;
35330
- align-items: center;
35331
- margin-top: 2rem;
35332
- padding-top: 1rem;
35333
- border-top: 1px solid #eee;
35334
- }
35376
+ .tags-list li {
35377
+ margin-bottom: 1rem;
35378
+ }
35335
35379
 
35336
- .pagination .page-info {
35337
- color: #6c757d;
35338
- font-size: 0.9rem;
35339
- }
35380
+ .tags-list .count {
35381
+ color: #6c757d;
35382
+ font-size: 0.9rem;
35383
+ }
35340
35384
 
35341
- /* Footer */
35342
- footer {
35343
- text-align: center;
35344
- padding: 2rem 0;
35345
- color: #6c757d;
35346
- font-size: 0.9rem;
35347
- }`;
35385
+ .tags-list .description {
35386
+ margin-top: 0.25rem;
35387
+ font-size: 0.9rem;
35388
+ color: #6c757d;
35389
+ }
35390
+
35391
+ /* Pagination */
35392
+ .pagination {
35393
+ display: flex;
35394
+ justify-content: space-between;
35395
+ align-items: center;
35396
+ margin-top: 2rem;
35397
+ padding-top: 1rem;
35398
+ border-top: 1px solid #eee;
35399
+ }
35348
35400
 
35349
- // src/cli/commands/templates/sample-post.ts
35350
- var samplePost = `---
35401
+ .pagination .page-info {
35402
+ color: #6c757d;
35403
+ font-size: 0.9rem;
35404
+ }
35405
+
35406
+ /* Footer */
35407
+ footer {
35408
+ text-align: center;
35409
+ padding: 2rem 0;
35410
+ color: #6c757d;
35411
+ font-size: 0.9rem;
35412
+ }`;
35413
+ }
35414
+ function getSamplePost() {
35415
+ return `---
35351
35416
  title: Welcome to Bunki
35352
35417
  date: 2025-01-15T12:00:00Z
35353
35418
  tags: [getting-started, bunki]
@@ -35398,64 +35463,6 @@ function hello() {
35398
35463
  4. Run \`bunki generate\` to build your site
35399
35464
  5. Run \`bunki serve\` to preview your site locally
35400
35465
  `;
35401
-
35402
- // src/cli/commands/templates/index.ts
35403
- var nunjucks3 = {
35404
- "base.njk": baseNjk,
35405
- "index.njk": indexNjk,
35406
- "post.njk": postNjk,
35407
- "tag.njk": tagNjk,
35408
- "tags.njk": tagsNjk,
35409
- "archive.njk": archiveNjk
35410
- };
35411
-
35412
- // src/cli/commands/init.ts
35413
- var defaultDependencies = {
35414
- createDefaultConfig,
35415
- ensureDir,
35416
- writeFile: (filePath, data) => Bun.write(filePath, data),
35417
- logger: console,
35418
- exit: (code) => process.exit(code)
35419
- };
35420
- async function handleInitCommand(options2, deps = defaultDependencies) {
35421
- try {
35422
- const configPath = path13.resolve(options2.config);
35423
- const configCreated = await deps.createDefaultConfig(configPath);
35424
- if (!configCreated) {
35425
- deps.logger.log(`
35426
- Skipped initialization because the config file already exists`);
35427
- return;
35428
- }
35429
- deps.logger.log("Creating directory structure...");
35430
- const baseDir = process.cwd();
35431
- const contentDir = path13.join(baseDir, "content");
35432
- const templatesDir = path13.join(baseDir, "templates");
35433
- const stylesDir = path13.join(templatesDir, "styles");
35434
- const publicDir = path13.join(baseDir, "public");
35435
- await deps.ensureDir(contentDir);
35436
- await deps.ensureDir(templatesDir);
35437
- await deps.ensureDir(stylesDir);
35438
- await deps.ensureDir(publicDir);
35439
- for (const [filename, content] of Object.entries(nunjucks3)) {
35440
- await deps.writeFile(path13.join(templatesDir, filename), content);
35441
- }
35442
- await deps.writeFile(path13.join(stylesDir, "main.css"), defaultCss);
35443
- await deps.writeFile(path13.join(contentDir, "welcome.md"), samplePost);
35444
- deps.logger.log(`
35445
- Initialization complete! Here are the next steps:`);
35446
- deps.logger.log("1. Edit bunki.config.ts to configure your site");
35447
- deps.logger.log("2. Add markdown files to the content directory");
35448
- deps.logger.log('3. Run "bunki generate" to build your site');
35449
- deps.logger.log('4. Run "bunki serve" to preview your site locally');
35450
- } catch (error) {
35451
- deps.logger.error("Error initializing site:", error);
35452
- deps.exit(1);
35453
- }
35454
- }
35455
- function registerInitCommand(program2, deps = defaultDependencies) {
35456
- return program2.command("init").description("Initialize a new site with default structure").option("-c, --config <file>", "Path to config file", "bunki.config.ts").action(async (options2) => {
35457
- await handleInitCommand(options2, deps);
35458
- });
35459
35466
  }
35460
35467
 
35461
35468
  // src/cli/commands/new-post.ts