bunki 0.5.1 → 0.5.3

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
@@ -2133,11 +2133,11 @@ var require_lib = __commonJS((exports, module) => {
2133
2133
  function lookupEscape(ch) {
2134
2134
  return escapeMap[ch];
2135
2135
  }
2136
- function _prettifyError(path3, withInternals, err) {
2136
+ function _prettifyError(path4, withInternals, err) {
2137
2137
  if (!err.Update) {
2138
2138
  err = new _exports.TemplateError(err);
2139
2139
  }
2140
- err.Update(path3);
2140
+ err.Update(path4);
2141
2141
  if (!withInternals) {
2142
2142
  var old = err;
2143
2143
  err = new Error(old.message);
@@ -2198,8 +2198,8 @@ var require_lib = __commonJS((exports, module) => {
2198
2198
  err.lineno = lineno;
2199
2199
  err.colno = colno;
2200
2200
  err.firstUpdate = true;
2201
- err.Update = function Update(path3) {
2202
- var msg = "(" + (path3 || "unknown path") + ")";
2201
+ err.Update = function Update(path4) {
2202
+ var msg = "(" + (path4 || "unknown path") + ")";
2203
2203
  if (this.firstUpdate) {
2204
2204
  if (this.lineno && this.colno) {
2205
2205
  msg += " [Line " + this.lineno + ", Column " + this.colno + "]";
@@ -6396,7 +6396,7 @@ var require_loader = __commonJS((exports, module) => {
6396
6396
  };
6397
6397
  return _setPrototypeOf(o, p);
6398
6398
  }
6399
- var path3 = __require("path");
6399
+ var path4 = __require("path");
6400
6400
  var _require = require_object();
6401
6401
  var EmitterObj = _require.EmitterObj;
6402
6402
  module.exports = /* @__PURE__ */ function(_EmitterObj) {
@@ -6406,7 +6406,7 @@ var require_loader = __commonJS((exports, module) => {
6406
6406
  }
6407
6407
  var _proto = Loader.prototype;
6408
6408
  _proto.resolve = function resolve(from, to) {
6409
- return path3.resolve(path3.dirname(from), to);
6409
+ return path4.resolve(path4.dirname(from), to);
6410
6410
  };
6411
6411
  _proto.isRelative = function isRelative(filename) {
6412
6412
  return filename.indexOf("./") === 0 || filename.indexOf("../") === 0;
@@ -6460,7 +6460,7 @@ var require_precompiled_loader = __commonJS((exports, module) => {
6460
6460
 
6461
6461
  // node_modules/picomatch/lib/constants.js
6462
6462
  var require_constants = __commonJS((exports, module) => {
6463
- var path3 = __require("path");
6463
+ var path4 = __require("path");
6464
6464
  var WIN_SLASH = "\\\\/";
6465
6465
  var WIN_NO_SLASH = `[^${WIN_SLASH}]`;
6466
6466
  var DOT_LITERAL = "\\.";
@@ -6582,7 +6582,7 @@ var require_constants = __commonJS((exports, module) => {
6582
6582
  CHAR_UNDERSCORE: 95,
6583
6583
  CHAR_VERTICAL_LINE: 124,
6584
6584
  CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279,
6585
- SEP: path3.sep,
6585
+ SEP: path4.sep,
6586
6586
  extglobChars(chars) {
6587
6587
  return {
6588
6588
  "!": { type: "negate", open: "(?:(?!(?:", close: `))${chars.STAR})` },
@@ -6600,7 +6600,7 @@ var require_constants = __commonJS((exports, module) => {
6600
6600
 
6601
6601
  // node_modules/picomatch/lib/utils.js
6602
6602
  var require_utils = __commonJS((exports) => {
6603
- var path3 = __require("path");
6603
+ var path4 = __require("path");
6604
6604
  var win32 = process.platform === "win32";
6605
6605
  var {
6606
6606
  REGEX_BACKSLASH,
@@ -6629,7 +6629,7 @@ var require_utils = __commonJS((exports) => {
6629
6629
  if (options2 && typeof options2.windows === "boolean") {
6630
6630
  return options2.windows;
6631
6631
  }
6632
- return win32 === true || path3.sep === "\\";
6632
+ return win32 === true || path4.sep === "\\";
6633
6633
  };
6634
6634
  exports.escapeLast = (input, char, lastIdx) => {
6635
6635
  const idx = input.lastIndexOf(char, lastIdx);
@@ -7753,7 +7753,7 @@ var require_parse = __commonJS((exports, module) => {
7753
7753
 
7754
7754
  // node_modules/picomatch/lib/picomatch.js
7755
7755
  var require_picomatch = __commonJS((exports, module) => {
7756
- var path3 = __require("path");
7756
+ var path4 = __require("path");
7757
7757
  var scan = require_scan();
7758
7758
  var parse2 = require_parse();
7759
7759
  var utils = require_utils();
@@ -7839,7 +7839,7 @@ var require_picomatch = __commonJS((exports, module) => {
7839
7839
  };
7840
7840
  picomatch.matchBase = (input, glob, options2, posix = utils.isWindows(options2)) => {
7841
7841
  const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options2);
7842
- return regex.test(path3.basename(input));
7842
+ return regex.test(path4.basename(input));
7843
7843
  };
7844
7844
  picomatch.isMatch = (str2, patterns, options2) => picomatch(patterns, options2)(str2);
7845
7845
  picomatch.parse = (pattern, options2) => {
@@ -7948,8 +7948,8 @@ var require_readdirp = __commonJS((exports, module) => {
7948
7948
  static get defaultOptions() {
7949
7949
  return {
7950
7950
  root: ".",
7951
- fileFilter: (path3) => true,
7952
- directoryFilter: (path3) => true,
7951
+ fileFilter: (path4) => true,
7952
+ directoryFilter: (path4) => true,
7953
7953
  type: FILE_TYPE,
7954
7954
  lstat: false,
7955
7955
  depth: 2147483648,
@@ -7968,7 +7968,7 @@ var require_readdirp = __commonJS((exports, module) => {
7968
7968
  this._directoryFilter = normalizeFilter(opts.directoryFilter);
7969
7969
  const statMethod = opts.lstat ? lstat : stat;
7970
7970
  if (wantBigintFsStats) {
7971
- this._stat = (path3) => statMethod(path3, { bigint: true });
7971
+ this._stat = (path4) => statMethod(path4, { bigint: true });
7972
7972
  } else {
7973
7973
  this._stat = statMethod;
7974
7974
  }
@@ -7990,9 +7990,9 @@ var require_readdirp = __commonJS((exports, module) => {
7990
7990
  this.reading = true;
7991
7991
  try {
7992
7992
  while (!this.destroyed && batch > 0) {
7993
- const { path: path3, depth, files = [] } = this.parent || {};
7993
+ const { path: path4, depth, files = [] } = this.parent || {};
7994
7994
  if (files.length > 0) {
7995
- const slice = files.splice(0, batch).map((dirent) => this._formatEntry(dirent, path3));
7995
+ const slice = files.splice(0, batch).map((dirent) => this._formatEntry(dirent, path4));
7996
7996
  for (const entry of await Promise.all(slice)) {
7997
7997
  if (this.destroyed)
7998
7998
  return;
@@ -8029,20 +8029,20 @@ var require_readdirp = __commonJS((exports, module) => {
8029
8029
  this.reading = false;
8030
8030
  }
8031
8031
  }
8032
- async _exploreDir(path3, depth) {
8032
+ async _exploreDir(path4, depth) {
8033
8033
  let files;
8034
8034
  try {
8035
- files = await readdir(path3, this._rdOptions);
8035
+ files = await readdir(path4, this._rdOptions);
8036
8036
  } catch (error) {
8037
8037
  this._onError(error);
8038
8038
  }
8039
- return { files, depth, path: path3 };
8039
+ return { files, depth, path: path4 };
8040
8040
  }
8041
- async _formatEntry(dirent, path3) {
8041
+ async _formatEntry(dirent, path4) {
8042
8042
  let entry;
8043
8043
  try {
8044
8044
  const basename = this._isDirent ? dirent.name : dirent;
8045
- const fullPath = sysPath.resolve(sysPath.join(path3, basename));
8045
+ const fullPath = sysPath.resolve(sysPath.join(path4, basename));
8046
8046
  entry = { path: sysPath.relative(this._root, fullPath), fullPath, basename };
8047
8047
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
8048
8048
  } catch (err) {
@@ -8131,24 +8131,24 @@ var require_normalize_path = __commonJS((exports, module) => {
8131
8131
  * Copyright (c) 2014-2018, Jon Schlinkert.
8132
8132
  * Released under the MIT License.
8133
8133
  */
8134
- module.exports = function(path3, stripTrailing) {
8135
- if (typeof path3 !== "string") {
8134
+ module.exports = function(path4, stripTrailing) {
8135
+ if (typeof path4 !== "string") {
8136
8136
  throw new TypeError("expected path to be a string");
8137
8137
  }
8138
- if (path3 === "\\" || path3 === "/")
8138
+ if (path4 === "\\" || path4 === "/")
8139
8139
  return "/";
8140
- var len = path3.length;
8140
+ var len = path4.length;
8141
8141
  if (len <= 1)
8142
- return path3;
8142
+ return path4;
8143
8143
  var prefix = "";
8144
- if (len > 4 && path3[3] === "\\") {
8145
- var ch = path3[2];
8146
- if ((ch === "?" || ch === ".") && path3.slice(0, 2) === "\\\\") {
8147
- path3 = path3.slice(2);
8144
+ if (len > 4 && path4[3] === "\\") {
8145
+ var ch = path4[2];
8146
+ if ((ch === "?" || ch === ".") && path4.slice(0, 2) === "\\\\") {
8147
+ path4 = path4.slice(2);
8148
8148
  prefix = "//";
8149
8149
  }
8150
8150
  }
8151
- var segs = path3.split(/[/\\]+/);
8151
+ var segs = path4.split(/[/\\]+/);
8152
8152
  if (stripTrailing !== false && segs[segs.length - 1] === "") {
8153
8153
  segs.pop();
8154
8154
  }
@@ -8183,17 +8183,17 @@ var require_anymatch = __commonJS((exports, module) => {
8183
8183
  if (!isList && typeof _path !== "string") {
8184
8184
  throw new TypeError("anymatch: second argument must be a string: got " + Object.prototype.toString.call(_path));
8185
8185
  }
8186
- const path3 = normalizePath(_path, false);
8186
+ const path4 = normalizePath(_path, false);
8187
8187
  for (let index = 0;index < negPatterns.length; index++) {
8188
8188
  const nglob = negPatterns[index];
8189
- if (nglob(path3)) {
8189
+ if (nglob(path4)) {
8190
8190
  return returnIndex ? -1 : false;
8191
8191
  }
8192
8192
  }
8193
- const applied = isList && [path3].concat(args.slice(1));
8193
+ const applied = isList && [path4].concat(args.slice(1));
8194
8194
  for (let index = 0;index < patterns.length; index++) {
8195
8195
  const pattern = patterns[index];
8196
- if (isList ? pattern(...applied) : pattern(path3)) {
8196
+ if (isList ? pattern(...applied) : pattern(path4)) {
8197
8197
  return returnIndex ? index : true;
8198
8198
  }
8199
8199
  }
@@ -9712,10 +9712,10 @@ var require_binary_extensions = __commonJS((exports, module) => {
9712
9712
 
9713
9713
  // node_modules/is-binary-path/index.js
9714
9714
  var require_is_binary_path = __commonJS((exports, module) => {
9715
- var path3 = __require("path");
9715
+ var path4 = __require("path");
9716
9716
  var binaryExtensions = require_binary_extensions();
9717
9717
  var extensions = new Set(binaryExtensions);
9718
- module.exports = (filePath) => extensions.has(path3.extname(filePath).slice(1).toLowerCase());
9718
+ module.exports = (filePath) => extensions.has(path4.extname(filePath).slice(1).toLowerCase());
9719
9719
  });
9720
9720
 
9721
9721
  // node_modules/chokidar/lib/constants.js
@@ -9841,16 +9841,16 @@ var require_nodefs_handler = __commonJS((exports, module) => {
9841
9841
  };
9842
9842
  var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
9843
9843
  var FsWatchInstances = new Map;
9844
- function createFsWatchInstance(path3, options2, listener, errHandler, emitRaw) {
9844
+ function createFsWatchInstance(path4, options2, listener, errHandler, emitRaw) {
9845
9845
  const handleEvent = (rawEvent, evPath) => {
9846
- listener(path3);
9847
- emitRaw(rawEvent, evPath, { watchedPath: path3 });
9848
- if (evPath && path3 !== evPath) {
9849
- fsWatchBroadcast(sysPath.resolve(path3, evPath), KEY_LISTENERS, sysPath.join(path3, evPath));
9846
+ listener(path4);
9847
+ emitRaw(rawEvent, evPath, { watchedPath: path4 });
9848
+ if (evPath && path4 !== evPath) {
9849
+ fsWatchBroadcast(sysPath.resolve(path4, evPath), KEY_LISTENERS, sysPath.join(path4, evPath));
9850
9850
  }
9851
9851
  };
9852
9852
  try {
9853
- return fs2.watch(path3, options2, handleEvent);
9853
+ return fs2.watch(path4, options2, handleEvent);
9854
9854
  } catch (error) {
9855
9855
  errHandler(error);
9856
9856
  }
@@ -9863,12 +9863,12 @@ var require_nodefs_handler = __commonJS((exports, module) => {
9863
9863
  listener(val1, val2, val3);
9864
9864
  });
9865
9865
  };
9866
- var setFsWatchListener = (path3, fullPath, options2, handlers) => {
9866
+ var setFsWatchListener = (path4, fullPath, options2, handlers) => {
9867
9867
  const { listener, errHandler, rawEmitter } = handlers;
9868
9868
  let cont = FsWatchInstances.get(fullPath);
9869
9869
  let watcher;
9870
9870
  if (!options2.persistent) {
9871
- watcher = createFsWatchInstance(path3, options2, listener, errHandler, rawEmitter);
9871
+ watcher = createFsWatchInstance(path4, options2, listener, errHandler, rawEmitter);
9872
9872
  return watcher.close.bind(watcher);
9873
9873
  }
9874
9874
  if (cont) {
@@ -9876,7 +9876,7 @@ var require_nodefs_handler = __commonJS((exports, module) => {
9876
9876
  addAndConvert(cont, KEY_ERR, errHandler);
9877
9877
  addAndConvert(cont, KEY_RAW, rawEmitter);
9878
9878
  } else {
9879
- watcher = createFsWatchInstance(path3, options2, fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), errHandler, fsWatchBroadcast.bind(null, fullPath, KEY_RAW));
9879
+ watcher = createFsWatchInstance(path4, options2, fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), errHandler, fsWatchBroadcast.bind(null, fullPath, KEY_RAW));
9880
9880
  if (!watcher)
9881
9881
  return;
9882
9882
  watcher.on(EV_ERROR, async (error) => {
@@ -9884,7 +9884,7 @@ var require_nodefs_handler = __commonJS((exports, module) => {
9884
9884
  cont.watcherUnusable = true;
9885
9885
  if (isWindows && error.code === "EPERM") {
9886
9886
  try {
9887
- const fd = await open(path3, "r");
9887
+ const fd = await open(path4, "r");
9888
9888
  await close(fd);
9889
9889
  broadcastErr(error);
9890
9890
  } catch (err) {}
@@ -9914,7 +9914,7 @@ var require_nodefs_handler = __commonJS((exports, module) => {
9914
9914
  };
9915
9915
  };
9916
9916
  var FsWatchFileInstances = new Map;
9917
- var setFsWatchFileListener = (path3, fullPath, options2, handlers) => {
9917
+ var setFsWatchFileListener = (path4, fullPath, options2, handlers) => {
9918
9918
  const { listener, rawEmitter } = handlers;
9919
9919
  let cont = FsWatchFileInstances.get(fullPath);
9920
9920
  let listeners = new Set;
@@ -9940,7 +9940,7 @@ var require_nodefs_handler = __commonJS((exports, module) => {
9940
9940
  });
9941
9941
  const currmtime = curr.mtimeMs;
9942
9942
  if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
9943
- foreach(cont.listeners, (listener2) => listener2(path3, curr));
9943
+ foreach(cont.listeners, (listener2) => listener2(path4, curr));
9944
9944
  }
9945
9945
  })
9946
9946
  };
@@ -9963,25 +9963,25 @@ var require_nodefs_handler = __commonJS((exports, module) => {
9963
9963
  this.fsw = fsW;
9964
9964
  this._boundHandleError = (error) => fsW._handleError(error);
9965
9965
  }
9966
- _watchWithNodeFs(path3, listener) {
9966
+ _watchWithNodeFs(path4, listener) {
9967
9967
  const opts = this.fsw.options;
9968
- const directory = sysPath.dirname(path3);
9969
- const basename = sysPath.basename(path3);
9968
+ const directory = sysPath.dirname(path4);
9969
+ const basename = sysPath.basename(path4);
9970
9970
  const parent = this.fsw._getWatchedDir(directory);
9971
9971
  parent.add(basename);
9972
- const absolutePath = sysPath.resolve(path3);
9972
+ const absolutePath = sysPath.resolve(path4);
9973
9973
  const options2 = { persistent: opts.persistent };
9974
9974
  if (!listener)
9975
9975
  listener = EMPTY_FN;
9976
9976
  let closer;
9977
9977
  if (opts.usePolling) {
9978
9978
  options2.interval = opts.enableBinaryInterval && isBinaryPath(basename) ? opts.binaryInterval : opts.interval;
9979
- closer = setFsWatchFileListener(path3, absolutePath, options2, {
9979
+ closer = setFsWatchFileListener(path4, absolutePath, options2, {
9980
9980
  listener,
9981
9981
  rawEmitter: this.fsw._emitRaw
9982
9982
  });
9983
9983
  } else {
9984
- closer = setFsWatchListener(path3, absolutePath, options2, {
9984
+ closer = setFsWatchListener(path4, absolutePath, options2, {
9985
9985
  listener,
9986
9986
  errHandler: this._boundHandleError,
9987
9987
  rawEmitter: this.fsw._emitRaw
@@ -9999,7 +9999,7 @@ var require_nodefs_handler = __commonJS((exports, module) => {
9999
9999
  let prevStats = stats;
10000
10000
  if (parent.has(basename))
10001
10001
  return;
10002
- const listener = async (path3, newStats) => {
10002
+ const listener = async (path4, newStats) => {
10003
10003
  if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
10004
10004
  return;
10005
10005
  if (!newStats || newStats.mtimeMs === 0) {
@@ -10013,9 +10013,9 @@ var require_nodefs_handler = __commonJS((exports, module) => {
10013
10013
  this.fsw._emit(EV_CHANGE, file, newStats2);
10014
10014
  }
10015
10015
  if (isLinux && prevStats.ino !== newStats2.ino) {
10016
- this.fsw._closeFile(path3);
10016
+ this.fsw._closeFile(path4);
10017
10017
  prevStats = newStats2;
10018
- this.fsw._addPathCloser(path3, this._watchWithNodeFs(file, listener));
10018
+ this.fsw._addPathCloser(path4, this._watchWithNodeFs(file, listener));
10019
10019
  } else {
10020
10020
  prevStats = newStats2;
10021
10021
  }
@@ -10039,7 +10039,7 @@ var require_nodefs_handler = __commonJS((exports, module) => {
10039
10039
  }
10040
10040
  return closer;
10041
10041
  }
10042
- async _handleSymlink(entry, directory, path3, item) {
10042
+ async _handleSymlink(entry, directory, path4, item) {
10043
10043
  if (this.fsw.closed) {
10044
10044
  return;
10045
10045
  }
@@ -10049,7 +10049,7 @@ var require_nodefs_handler = __commonJS((exports, module) => {
10049
10049
  this.fsw._incrReadyCount();
10050
10050
  let linkPath;
10051
10051
  try {
10052
- linkPath = await fsrealpath(path3);
10052
+ linkPath = await fsrealpath(path4);
10053
10053
  } catch (e) {
10054
10054
  this.fsw._emitReady();
10055
10055
  return true;
@@ -10059,12 +10059,12 @@ var require_nodefs_handler = __commonJS((exports, module) => {
10059
10059
  if (dir.has(item)) {
10060
10060
  if (this.fsw._symlinkPaths.get(full) !== linkPath) {
10061
10061
  this.fsw._symlinkPaths.set(full, linkPath);
10062
- this.fsw._emit(EV_CHANGE, path3, entry.stats);
10062
+ this.fsw._emit(EV_CHANGE, path4, entry.stats);
10063
10063
  }
10064
10064
  } else {
10065
10065
  dir.add(item);
10066
10066
  this.fsw._symlinkPaths.set(full, linkPath);
10067
- this.fsw._emit(EV_ADD, path3, entry.stats);
10067
+ this.fsw._emit(EV_ADD, path4, entry.stats);
10068
10068
  }
10069
10069
  this.fsw._emitReady();
10070
10070
  return true;
@@ -10093,9 +10093,9 @@ var require_nodefs_handler = __commonJS((exports, module) => {
10093
10093
  return;
10094
10094
  }
10095
10095
  const item = entry.path;
10096
- let path3 = sysPath.join(directory, item);
10096
+ let path4 = sysPath.join(directory, item);
10097
10097
  current.add(item);
10098
- if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path3, item)) {
10098
+ if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path4, item)) {
10099
10099
  return;
10100
10100
  }
10101
10101
  if (this.fsw.closed) {
@@ -10104,8 +10104,8 @@ var require_nodefs_handler = __commonJS((exports, module) => {
10104
10104
  }
10105
10105
  if (item === target || !target && !previous.has(item)) {
10106
10106
  this.fsw._incrReadyCount();
10107
- path3 = sysPath.join(dir, sysPath.relative(dir, path3));
10108
- this._addToNodeFs(path3, initialAdd, wh, depth + 1);
10107
+ path4 = sysPath.join(dir, sysPath.relative(dir, path4));
10108
+ this._addToNodeFs(path4, initialAdd, wh, depth + 1);
10109
10109
  }
10110
10110
  }).on(EV_ERROR, this._boundHandleError);
10111
10111
  return new Promise((resolve) => stream.once(STR_END, () => {
@@ -10153,13 +10153,13 @@ var require_nodefs_handler = __commonJS((exports, module) => {
10153
10153
  }
10154
10154
  return closer;
10155
10155
  }
10156
- async _addToNodeFs(path3, initialAdd, priorWh, depth, target) {
10156
+ async _addToNodeFs(path4, initialAdd, priorWh, depth, target) {
10157
10157
  const ready = this.fsw._emitReady;
10158
- if (this.fsw._isIgnored(path3) || this.fsw.closed) {
10158
+ if (this.fsw._isIgnored(path4) || this.fsw.closed) {
10159
10159
  ready();
10160
10160
  return false;
10161
10161
  }
10162
- const wh = this.fsw._getWatchHelpers(path3, depth);
10162
+ const wh = this.fsw._getWatchHelpers(path4, depth);
10163
10163
  if (!wh.hasGlob && priorWh) {
10164
10164
  wh.hasGlob = priorWh.hasGlob;
10165
10165
  wh.globFilter = priorWh.globFilter;
@@ -10174,11 +10174,11 @@ var require_nodefs_handler = __commonJS((exports, module) => {
10174
10174
  ready();
10175
10175
  return false;
10176
10176
  }
10177
- const follow = this.fsw.options.followSymlinks && !path3.includes(STAR) && !path3.includes(BRACE_START);
10177
+ const follow = this.fsw.options.followSymlinks && !path4.includes(STAR) && !path4.includes(BRACE_START);
10178
10178
  let closer;
10179
10179
  if (stats.isDirectory()) {
10180
- const absPath = sysPath.resolve(path3);
10181
- const targetPath = follow ? await fsrealpath(path3) : path3;
10180
+ const absPath = sysPath.resolve(path4);
10181
+ const targetPath = follow ? await fsrealpath(path4) : path4;
10182
10182
  if (this.fsw.closed)
10183
10183
  return;
10184
10184
  closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
@@ -10188,28 +10188,28 @@ var require_nodefs_handler = __commonJS((exports, module) => {
10188
10188
  this.fsw._symlinkPaths.set(absPath, targetPath);
10189
10189
  }
10190
10190
  } else if (stats.isSymbolicLink()) {
10191
- const targetPath = follow ? await fsrealpath(path3) : path3;
10191
+ const targetPath = follow ? await fsrealpath(path4) : path4;
10192
10192
  if (this.fsw.closed)
10193
10193
  return;
10194
10194
  const parent = sysPath.dirname(wh.watchPath);
10195
10195
  this.fsw._getWatchedDir(parent).add(wh.watchPath);
10196
10196
  this.fsw._emit(EV_ADD, wh.watchPath, stats);
10197
- closer = await this._handleDir(parent, stats, initialAdd, depth, path3, wh, targetPath);
10197
+ closer = await this._handleDir(parent, stats, initialAdd, depth, path4, wh, targetPath);
10198
10198
  if (this.fsw.closed)
10199
10199
  return;
10200
10200
  if (targetPath !== undefined) {
10201
- this.fsw._symlinkPaths.set(sysPath.resolve(path3), targetPath);
10201
+ this.fsw._symlinkPaths.set(sysPath.resolve(path4), targetPath);
10202
10202
  }
10203
10203
  } else {
10204
10204
  closer = this._handleFile(wh.watchPath, stats, initialAdd);
10205
10205
  }
10206
10206
  ready();
10207
- this.fsw._addPathCloser(path3, closer);
10207
+ this.fsw._addPathCloser(path4, closer);
10208
10208
  return false;
10209
10209
  } catch (error) {
10210
10210
  if (this.fsw._handleError(error)) {
10211
10211
  ready();
10212
- return path3;
10212
+ return path4;
10213
10213
  }
10214
10214
  }
10215
10215
  }
@@ -10229,9 +10229,9 @@ var require_fsevents2 = __commonJS((exports) => {
10229
10229
  }
10230
10230
  var Native = require_fsevents();
10231
10231
  var events = Native.constants;
10232
- function watch(path3, since, handler) {
10233
- if (typeof path3 !== "string") {
10234
- throw new TypeError(`fsevents argument 1 must be a string and not a ${typeof path3}`);
10232
+ function watch(path4, since, handler) {
10233
+ if (typeof path4 !== "string") {
10234
+ throw new TypeError(`fsevents argument 1 must be a string and not a ${typeof path4}`);
10235
10235
  }
10236
10236
  if (typeof since === "function" && typeof handler === "undefined") {
10237
10237
  handler = since;
@@ -10243,18 +10243,18 @@ var require_fsevents2 = __commonJS((exports) => {
10243
10243
  if (typeof handler !== "function") {
10244
10244
  throw new TypeError(`fsevents argument 3 must be a function and not a ${typeof handler}`);
10245
10245
  }
10246
- let instance = Native.start(Native.global, path3, since, handler);
10246
+ let instance = Native.start(Native.global, path4, since, handler);
10247
10247
  if (!instance)
10248
- throw new Error(`could not watch: ${path3}`);
10248
+ throw new Error(`could not watch: ${path4}`);
10249
10249
  return () => {
10250
10250
  const result = instance ? Promise.resolve(instance).then(Native.stop) : Promise.resolve(undefined);
10251
10251
  instance = undefined;
10252
10252
  return result;
10253
10253
  };
10254
10254
  }
10255
- function getInfo(path3, flags) {
10255
+ function getInfo(path4, flags) {
10256
10256
  return {
10257
- path: path3,
10257
+ path: path4,
10258
10258
  flags,
10259
10259
  event: getEventType(flags),
10260
10260
  type: getFileType(flags),
@@ -10371,18 +10371,18 @@ var require_fsevents_handler = __commonJS((exports, module) => {
10371
10371
  131840,
10372
10372
  262912
10373
10373
  ]);
10374
- var createFSEventsInstance = (path3, callback) => {
10375
- const stop = fsevents.watch(path3, callback);
10374
+ var createFSEventsInstance = (path4, callback) => {
10375
+ const stop = fsevents.watch(path4, callback);
10376
10376
  return { stop };
10377
10377
  };
10378
- function setFSEventsListener(path3, realPath, listener, rawEmitter) {
10378
+ function setFSEventsListener(path4, realPath, listener, rawEmitter) {
10379
10379
  let watchPath = sysPath.extname(realPath) ? sysPath.dirname(realPath) : realPath;
10380
10380
  const parentPath = sysPath.dirname(watchPath);
10381
10381
  let cont = FSEventsWatchers.get(watchPath);
10382
10382
  if (couldConsolidate(parentPath)) {
10383
10383
  watchPath = parentPath;
10384
10384
  }
10385
- const resolvedPath = sysPath.resolve(path3);
10385
+ const resolvedPath = sysPath.resolve(path4);
10386
10386
  const hasSymlink = resolvedPath !== realPath;
10387
10387
  const filteredListener = (fullPath, flags, info) => {
10388
10388
  if (hasSymlink)
@@ -10432,10 +10432,10 @@ var require_fsevents_handler = __commonJS((exports, module) => {
10432
10432
  }
10433
10433
  };
10434
10434
  }
10435
- var couldConsolidate = (path3) => {
10435
+ var couldConsolidate = (path4) => {
10436
10436
  let count = 0;
10437
10437
  for (const watchPath of FSEventsWatchers.keys()) {
10438
- if (watchPath.indexOf(path3) === 0) {
10438
+ if (watchPath.indexOf(path4) === 0) {
10439
10439
  count++;
10440
10440
  if (count >= consolidateThreshhold) {
10441
10441
  return true;
@@ -10445,9 +10445,9 @@ var require_fsevents_handler = __commonJS((exports, module) => {
10445
10445
  return false;
10446
10446
  };
10447
10447
  var canUse = () => fsevents && FSEventsWatchers.size < 128;
10448
- var calcDepth = (path3, root) => {
10448
+ var calcDepth = (path4, root) => {
10449
10449
  let i = 0;
10450
- while (!path3.indexOf(root) && (path3 = sysPath.dirname(path3)) !== root)
10450
+ while (!path4.indexOf(root) && (path4 = sysPath.dirname(path4)) !== root)
10451
10451
  i++;
10452
10452
  return i;
10453
10453
  };
@@ -10457,42 +10457,42 @@ var require_fsevents_handler = __commonJS((exports, module) => {
10457
10457
  constructor(fsw) {
10458
10458
  this.fsw = fsw;
10459
10459
  }
10460
- checkIgnored(path3, stats) {
10460
+ checkIgnored(path4, stats) {
10461
10461
  const ipaths = this.fsw._ignoredPaths;
10462
- if (this.fsw._isIgnored(path3, stats)) {
10463
- ipaths.add(path3);
10462
+ if (this.fsw._isIgnored(path4, stats)) {
10463
+ ipaths.add(path4);
10464
10464
  if (stats && stats.isDirectory()) {
10465
- ipaths.add(path3 + ROOT_GLOBSTAR);
10465
+ ipaths.add(path4 + ROOT_GLOBSTAR);
10466
10466
  }
10467
10467
  return true;
10468
10468
  }
10469
- ipaths.delete(path3);
10470
- ipaths.delete(path3 + ROOT_GLOBSTAR);
10469
+ ipaths.delete(path4);
10470
+ ipaths.delete(path4 + ROOT_GLOBSTAR);
10471
10471
  }
10472
- addOrChange(path3, fullPath, realPath, parent, watchedDir, item, info, opts) {
10472
+ addOrChange(path4, fullPath, realPath, parent, watchedDir, item, info, opts) {
10473
10473
  const event = watchedDir.has(item) ? EV_CHANGE : EV_ADD;
10474
- this.handleEvent(event, path3, fullPath, realPath, parent, watchedDir, item, info, opts);
10474
+ this.handleEvent(event, path4, fullPath, realPath, parent, watchedDir, item, info, opts);
10475
10475
  }
10476
- async checkExists(path3, fullPath, realPath, parent, watchedDir, item, info, opts) {
10476
+ async checkExists(path4, fullPath, realPath, parent, watchedDir, item, info, opts) {
10477
10477
  try {
10478
- const stats = await stat(path3);
10478
+ const stats = await stat(path4);
10479
10479
  if (this.fsw.closed)
10480
10480
  return;
10481
10481
  if (sameTypes(info, stats)) {
10482
- this.addOrChange(path3, fullPath, realPath, parent, watchedDir, item, info, opts);
10482
+ this.addOrChange(path4, fullPath, realPath, parent, watchedDir, item, info, opts);
10483
10483
  } else {
10484
- this.handleEvent(EV_UNLINK, path3, fullPath, realPath, parent, watchedDir, item, info, opts);
10484
+ this.handleEvent(EV_UNLINK, path4, fullPath, realPath, parent, watchedDir, item, info, opts);
10485
10485
  }
10486
10486
  } catch (error) {
10487
10487
  if (error.code === "EACCES") {
10488
- this.addOrChange(path3, fullPath, realPath, parent, watchedDir, item, info, opts);
10488
+ this.addOrChange(path4, fullPath, realPath, parent, watchedDir, item, info, opts);
10489
10489
  } else {
10490
- this.handleEvent(EV_UNLINK, path3, fullPath, realPath, parent, watchedDir, item, info, opts);
10490
+ this.handleEvent(EV_UNLINK, path4, fullPath, realPath, parent, watchedDir, item, info, opts);
10491
10491
  }
10492
10492
  }
10493
10493
  }
10494
- handleEvent(event, path3, fullPath, realPath, parent, watchedDir, item, info, opts) {
10495
- if (this.fsw.closed || this.checkIgnored(path3))
10494
+ handleEvent(event, path4, fullPath, realPath, parent, watchedDir, item, info, opts) {
10495
+ if (this.fsw.closed || this.checkIgnored(path4))
10496
10496
  return;
10497
10497
  if (event === EV_UNLINK) {
10498
10498
  const isDirectory = info.type === FSEVENT_TYPE_DIRECTORY;
@@ -10502,17 +10502,17 @@ var require_fsevents_handler = __commonJS((exports, module) => {
10502
10502
  } else {
10503
10503
  if (event === EV_ADD) {
10504
10504
  if (info.type === FSEVENT_TYPE_DIRECTORY)
10505
- this.fsw._getWatchedDir(path3);
10505
+ this.fsw._getWatchedDir(path4);
10506
10506
  if (info.type === FSEVENT_TYPE_SYMLINK && opts.followSymlinks) {
10507
10507
  const curDepth = opts.depth === undefined ? undefined : calcDepth(fullPath, realPath) + 1;
10508
- return this._addToFsEvents(path3, false, true, curDepth);
10508
+ return this._addToFsEvents(path4, false, true, curDepth);
10509
10509
  }
10510
10510
  this.fsw._getWatchedDir(parent).add(item);
10511
10511
  }
10512
10512
  const eventName = info.type === FSEVENT_TYPE_DIRECTORY ? event + DIR_SUFFIX : event;
10513
- this.fsw._emit(eventName, path3);
10513
+ this.fsw._emit(eventName, path4);
10514
10514
  if (eventName === EV_ADD_DIR)
10515
- this._addToFsEvents(path3, false, true);
10515
+ this._addToFsEvents(path4, false, true);
10516
10516
  }
10517
10517
  }
10518
10518
  _watchWithFsEvents(watchPath, realPath, transform, globFilter) {
@@ -10524,38 +10524,38 @@ var require_fsevents_handler = __commonJS((exports, module) => {
10524
10524
  return;
10525
10525
  if (opts.depth !== undefined && calcDepth(fullPath, realPath) > opts.depth)
10526
10526
  return;
10527
- const path3 = transform(sysPath.join(watchPath, sysPath.relative(watchPath, fullPath)));
10528
- if (globFilter && !globFilter(path3))
10527
+ const path4 = transform(sysPath.join(watchPath, sysPath.relative(watchPath, fullPath)));
10528
+ if (globFilter && !globFilter(path4))
10529
10529
  return;
10530
- const parent = sysPath.dirname(path3);
10531
- const item = sysPath.basename(path3);
10532
- const watchedDir = this.fsw._getWatchedDir(info.type === FSEVENT_TYPE_DIRECTORY ? path3 : parent);
10530
+ const parent = sysPath.dirname(path4);
10531
+ const item = sysPath.basename(path4);
10532
+ const watchedDir = this.fsw._getWatchedDir(info.type === FSEVENT_TYPE_DIRECTORY ? path4 : parent);
10533
10533
  if (wrongEventFlags.has(flags) || info.event === FSEVENT_UNKNOWN) {
10534
10534
  if (typeof opts.ignored === FUNCTION_TYPE) {
10535
10535
  let stats;
10536
10536
  try {
10537
- stats = await stat(path3);
10537
+ stats = await stat(path4);
10538
10538
  } catch (error) {}
10539
10539
  if (this.fsw.closed)
10540
10540
  return;
10541
- if (this.checkIgnored(path3, stats))
10541
+ if (this.checkIgnored(path4, stats))
10542
10542
  return;
10543
10543
  if (sameTypes(info, stats)) {
10544
- this.addOrChange(path3, fullPath, realPath, parent, watchedDir, item, info, opts);
10544
+ this.addOrChange(path4, fullPath, realPath, parent, watchedDir, item, info, opts);
10545
10545
  } else {
10546
- this.handleEvent(EV_UNLINK, path3, fullPath, realPath, parent, watchedDir, item, info, opts);
10546
+ this.handleEvent(EV_UNLINK, path4, fullPath, realPath, parent, watchedDir, item, info, opts);
10547
10547
  }
10548
10548
  } else {
10549
- this.checkExists(path3, fullPath, realPath, parent, watchedDir, item, info, opts);
10549
+ this.checkExists(path4, fullPath, realPath, parent, watchedDir, item, info, opts);
10550
10550
  }
10551
10551
  } else {
10552
10552
  switch (info.event) {
10553
10553
  case FSEVENT_CREATED:
10554
10554
  case FSEVENT_MODIFIED:
10555
- return this.addOrChange(path3, fullPath, realPath, parent, watchedDir, item, info, opts);
10555
+ return this.addOrChange(path4, fullPath, realPath, parent, watchedDir, item, info, opts);
10556
10556
  case FSEVENT_DELETED:
10557
10557
  case FSEVENT_MOVED:
10558
- return this.checkExists(path3, fullPath, realPath, parent, watchedDir, item, info, opts);
10558
+ return this.checkExists(path4, fullPath, realPath, parent, watchedDir, item, info, opts);
10559
10559
  }
10560
10560
  }
10561
10561
  };
@@ -10576,12 +10576,12 @@ var require_fsevents_handler = __commonJS((exports, module) => {
10576
10576
  return this.fsw._emitReady();
10577
10577
  }
10578
10578
  this.fsw._incrReadyCount();
10579
- this._addToFsEvents(linkTarget || linkPath, (path3) => {
10579
+ this._addToFsEvents(linkTarget || linkPath, (path4) => {
10580
10580
  let aliasedPath = linkPath;
10581
10581
  if (linkTarget && linkTarget !== DOT_SLASH) {
10582
- aliasedPath = path3.replace(linkTarget, linkPath);
10583
- } else if (path3 !== DOT_SLASH) {
10584
- aliasedPath = sysPath.join(linkPath, path3);
10582
+ aliasedPath = path4.replace(linkTarget, linkPath);
10583
+ } else if (path4 !== DOT_SLASH) {
10584
+ aliasedPath = sysPath.join(linkPath, path4);
10585
10585
  }
10586
10586
  return transform(aliasedPath);
10587
10587
  }, false, curDepth);
@@ -10605,19 +10605,19 @@ var require_fsevents_handler = __commonJS((exports, module) => {
10605
10605
  this.fsw._emit(isDir ? EV_ADD_DIR : EV_ADD, pp, stats);
10606
10606
  }
10607
10607
  }
10608
- initWatch(realPath, path3, wh, processPath) {
10608
+ initWatch(realPath, path4, wh, processPath) {
10609
10609
  if (this.fsw.closed)
10610
10610
  return;
10611
10611
  const closer = this._watchWithFsEvents(wh.watchPath, sysPath.resolve(realPath || wh.watchPath), processPath, wh.globFilter);
10612
- this.fsw._addPathCloser(path3, closer);
10612
+ this.fsw._addPathCloser(path4, closer);
10613
10613
  }
10614
- async _addToFsEvents(path3, transform, forceAdd, priorDepth) {
10614
+ async _addToFsEvents(path4, transform, forceAdd, priorDepth) {
10615
10615
  if (this.fsw.closed) {
10616
10616
  return;
10617
10617
  }
10618
10618
  const opts = this.fsw.options;
10619
10619
  const processPath = typeof transform === FUNCTION_TYPE ? transform : IDENTITY_FN;
10620
- const wh = this.fsw._getWatchHelpers(path3);
10620
+ const wh = this.fsw._getWatchHelpers(path4);
10621
10621
  try {
10622
10622
  const stats = await statMethods[wh.statMethod](wh.watchPath);
10623
10623
  if (this.fsw.closed)
@@ -10627,7 +10627,7 @@ var require_fsevents_handler = __commonJS((exports, module) => {
10627
10627
  }
10628
10628
  if (stats.isDirectory()) {
10629
10629
  if (!wh.globFilter)
10630
- this.emitAdd(processPath(path3), stats, processPath, opts, forceAdd);
10630
+ this.emitAdd(processPath(path4), stats, processPath, opts, forceAdd);
10631
10631
  if (priorDepth && priorDepth > opts.depth)
10632
10632
  return;
10633
10633
  this.fsw._readdirp(wh.watchPath, {
@@ -10663,13 +10663,13 @@ var require_fsevents_handler = __commonJS((exports, module) => {
10663
10663
  }
10664
10664
  if (opts.persistent && forceAdd !== true) {
10665
10665
  if (typeof transform === FUNCTION_TYPE) {
10666
- this.initWatch(undefined, path3, wh, processPath);
10666
+ this.initWatch(undefined, path4, wh, processPath);
10667
10667
  } else {
10668
10668
  let realPath;
10669
10669
  try {
10670
10670
  realPath = await realpath(wh.watchPath);
10671
10671
  } catch (e) {}
10672
- this.initWatch(realPath, path3, wh, processPath);
10672
+ this.initWatch(realPath, path4, wh, processPath);
10673
10673
  }
10674
10674
  }
10675
10675
  }
@@ -10760,20 +10760,20 @@ var require_chokidar = __commonJS((exports) => {
10760
10760
  }
10761
10761
  return str2;
10762
10762
  };
10763
- var normalizePathToUnix = (path3) => toUnix(sysPath.normalize(toUnix(path3)));
10764
- var normalizeIgnored = (cwd = EMPTY_STR) => (path3) => {
10765
- if (typeof path3 !== STRING_TYPE)
10766
- return path3;
10767
- return normalizePathToUnix(sysPath.isAbsolute(path3) ? path3 : sysPath.join(cwd, path3));
10763
+ var normalizePathToUnix = (path4) => toUnix(sysPath.normalize(toUnix(path4)));
10764
+ var normalizeIgnored = (cwd = EMPTY_STR) => (path4) => {
10765
+ if (typeof path4 !== STRING_TYPE)
10766
+ return path4;
10767
+ return normalizePathToUnix(sysPath.isAbsolute(path4) ? path4 : sysPath.join(cwd, path4));
10768
10768
  };
10769
- var getAbsolutePath = (path3, cwd) => {
10770
- if (sysPath.isAbsolute(path3)) {
10771
- return path3;
10769
+ var getAbsolutePath = (path4, cwd) => {
10770
+ if (sysPath.isAbsolute(path4)) {
10771
+ return path4;
10772
10772
  }
10773
- if (path3.startsWith(BANG)) {
10774
- return BANG + sysPath.join(cwd, path3.slice(1));
10773
+ if (path4.startsWith(BANG)) {
10774
+ return BANG + sysPath.join(cwd, path4.slice(1));
10775
10775
  }
10776
- return sysPath.join(cwd, path3);
10776
+ return sysPath.join(cwd, path4);
10777
10777
  };
10778
10778
  var undef = (opts, key) => opts[key] === undefined;
10779
10779
 
@@ -10830,17 +10830,17 @@ var require_chokidar = __commonJS((exports) => {
10830
10830
  var STAT_METHOD_L = "lstat";
10831
10831
 
10832
10832
  class WatchHelper {
10833
- constructor(path3, watchPath, follow, fsw) {
10833
+ constructor(path4, watchPath, follow, fsw) {
10834
10834
  this.fsw = fsw;
10835
- this.path = path3 = path3.replace(REPLACER_RE, EMPTY_STR);
10835
+ this.path = path4 = path4.replace(REPLACER_RE, EMPTY_STR);
10836
10836
  this.watchPath = watchPath;
10837
10837
  this.fullWatchPath = sysPath.resolve(watchPath);
10838
- this.hasGlob = watchPath !== path3;
10839
- if (path3 === EMPTY_STR)
10838
+ this.hasGlob = watchPath !== path4;
10839
+ if (path4 === EMPTY_STR)
10840
10840
  this.hasGlob = false;
10841
10841
  this.globSymlink = this.hasGlob && follow ? undefined : false;
10842
- this.globFilter = this.hasGlob ? anymatch(path3, undefined, ANYMATCH_OPTS) : false;
10843
- this.dirParts = this.getDirParts(path3);
10842
+ this.globFilter = this.hasGlob ? anymatch(path4, undefined, ANYMATCH_OPTS) : false;
10843
+ this.dirParts = this.getDirParts(path4);
10844
10844
  this.dirParts.forEach((parts) => {
10845
10845
  if (parts.length > 1)
10846
10846
  parts.pop();
@@ -10868,13 +10868,13 @@ var require_chokidar = __commonJS((exports) => {
10868
10868
  const matchesGlob = this.hasGlob && typeof this.globFilter === FUNCTION_TYPE ? this.globFilter(resolvedPath) : true;
10869
10869
  return matchesGlob && this.fsw._isntIgnored(resolvedPath, stats) && this.fsw._hasReadPermissions(stats);
10870
10870
  }
10871
- getDirParts(path3) {
10871
+ getDirParts(path4) {
10872
10872
  if (!this.hasGlob)
10873
10873
  return [];
10874
10874
  const parts = [];
10875
- const expandedPath = path3.includes(BRACE_START) ? braces.expand(path3) : [path3];
10876
- expandedPath.forEach((path4) => {
10877
- parts.push(sysPath.relative(this.watchPath, path4).split(SLASH_OR_BACK_SLASH_RE));
10875
+ const expandedPath = path4.includes(BRACE_START) ? braces.expand(path4) : [path4];
10876
+ expandedPath.forEach((path5) => {
10877
+ parts.push(sysPath.relative(this.watchPath, path5).split(SLASH_OR_BACK_SLASH_RE));
10878
10878
  });
10879
10879
  return parts;
10880
10880
  }
@@ -10990,21 +10990,21 @@ var require_chokidar = __commonJS((exports) => {
10990
10990
  this.closed = false;
10991
10991
  let paths = unifyPaths(paths_);
10992
10992
  if (cwd) {
10993
- paths = paths.map((path3) => {
10994
- const absPath = getAbsolutePath(path3, cwd);
10995
- if (disableGlobbing || !isGlob(path3)) {
10993
+ paths = paths.map((path4) => {
10994
+ const absPath = getAbsolutePath(path4, cwd);
10995
+ if (disableGlobbing || !isGlob(path4)) {
10996
10996
  return absPath;
10997
10997
  }
10998
10998
  return normalizePath(absPath);
10999
10999
  });
11000
11000
  }
11001
- paths = paths.filter((path3) => {
11002
- if (path3.startsWith(BANG)) {
11003
- this._ignoredPaths.add(path3.slice(1));
11001
+ paths = paths.filter((path4) => {
11002
+ if (path4.startsWith(BANG)) {
11003
+ this._ignoredPaths.add(path4.slice(1));
11004
11004
  return false;
11005
11005
  }
11006
- this._ignoredPaths.delete(path3);
11007
- this._ignoredPaths.delete(path3 + SLASH_GLOBSTAR);
11006
+ this._ignoredPaths.delete(path4);
11007
+ this._ignoredPaths.delete(path4 + SLASH_GLOBSTAR);
11008
11008
  this._userIgnored = undefined;
11009
11009
  return true;
11010
11010
  });
@@ -11013,13 +11013,13 @@ var require_chokidar = __commonJS((exports) => {
11013
11013
  this._readyCount = paths.length;
11014
11014
  if (this.options.persistent)
11015
11015
  this._readyCount += paths.length;
11016
- paths.forEach((path3) => this._fsEventsHandler._addToFsEvents(path3));
11016
+ paths.forEach((path4) => this._fsEventsHandler._addToFsEvents(path4));
11017
11017
  } else {
11018
11018
  if (!this._readyCount)
11019
11019
  this._readyCount = 0;
11020
11020
  this._readyCount += paths.length;
11021
- Promise.all(paths.map(async (path3) => {
11022
- const res = await this._nodeFsHandler._addToNodeFs(path3, !_internal, 0, 0, _origAdd);
11021
+ Promise.all(paths.map(async (path4) => {
11022
+ const res = await this._nodeFsHandler._addToNodeFs(path4, !_internal, 0, 0, _origAdd);
11023
11023
  if (res)
11024
11024
  this._emitReady();
11025
11025
  return res;
@@ -11038,16 +11038,16 @@ var require_chokidar = __commonJS((exports) => {
11038
11038
  return this;
11039
11039
  const paths = unifyPaths(paths_);
11040
11040
  const { cwd } = this.options;
11041
- paths.forEach((path3) => {
11042
- if (!sysPath.isAbsolute(path3) && !this._closers.has(path3)) {
11041
+ paths.forEach((path4) => {
11042
+ if (!sysPath.isAbsolute(path4) && !this._closers.has(path4)) {
11043
11043
  if (cwd)
11044
- path3 = sysPath.join(cwd, path3);
11045
- path3 = sysPath.resolve(path3);
11044
+ path4 = sysPath.join(cwd, path4);
11045
+ path4 = sysPath.resolve(path4);
11046
11046
  }
11047
- this._closePath(path3);
11048
- this._ignoredPaths.add(path3);
11049
- if (this._watched.has(path3)) {
11050
- this._ignoredPaths.add(path3 + SLASH_GLOBSTAR);
11047
+ this._closePath(path4);
11048
+ this._ignoredPaths.add(path4);
11049
+ if (this._watched.has(path4)) {
11050
+ this._ignoredPaths.add(path4 + SLASH_GLOBSTAR);
11051
11051
  }
11052
11052
  this._userIgnored = undefined;
11053
11053
  });
@@ -11090,15 +11090,15 @@ var require_chokidar = __commonJS((exports) => {
11090
11090
  if (event !== EV_ERROR)
11091
11091
  this.emit(EV_ALL, ...args);
11092
11092
  }
11093
- async _emit(event, path3, val1, val2, val3) {
11093
+ async _emit(event, path4, val1, val2, val3) {
11094
11094
  if (this.closed)
11095
11095
  return;
11096
11096
  const opts = this.options;
11097
11097
  if (isWindows)
11098
- path3 = sysPath.normalize(path3);
11098
+ path4 = sysPath.normalize(path4);
11099
11099
  if (opts.cwd)
11100
- path3 = sysPath.relative(opts.cwd, path3);
11101
- const args = [event, path3];
11100
+ path4 = sysPath.relative(opts.cwd, path4);
11101
+ const args = [event, path4];
11102
11102
  if (val3 !== undefined)
11103
11103
  args.push(val1, val2, val3);
11104
11104
  else if (val2 !== undefined)
@@ -11107,25 +11107,25 @@ var require_chokidar = __commonJS((exports) => {
11107
11107
  args.push(val1);
11108
11108
  const awf = opts.awaitWriteFinish;
11109
11109
  let pw;
11110
- if (awf && (pw = this._pendingWrites.get(path3))) {
11110
+ if (awf && (pw = this._pendingWrites.get(path4))) {
11111
11111
  pw.lastChange = new Date;
11112
11112
  return this;
11113
11113
  }
11114
11114
  if (opts.atomic) {
11115
11115
  if (event === EV_UNLINK) {
11116
- this._pendingUnlinks.set(path3, args);
11116
+ this._pendingUnlinks.set(path4, args);
11117
11117
  setTimeout(() => {
11118
- this._pendingUnlinks.forEach((entry, path4) => {
11118
+ this._pendingUnlinks.forEach((entry, path5) => {
11119
11119
  this.emit(...entry);
11120
11120
  this.emit(EV_ALL, ...entry);
11121
- this._pendingUnlinks.delete(path4);
11121
+ this._pendingUnlinks.delete(path5);
11122
11122
  });
11123
11123
  }, typeof opts.atomic === "number" ? opts.atomic : 100);
11124
11124
  return this;
11125
11125
  }
11126
- if (event === EV_ADD && this._pendingUnlinks.has(path3)) {
11126
+ if (event === EV_ADD && this._pendingUnlinks.has(path4)) {
11127
11127
  event = args[0] = EV_CHANGE;
11128
- this._pendingUnlinks.delete(path3);
11128
+ this._pendingUnlinks.delete(path4);
11129
11129
  }
11130
11130
  }
11131
11131
  if (awf && (event === EV_ADD || event === EV_CHANGE) && this._readyEmitted) {
@@ -11143,16 +11143,16 @@ var require_chokidar = __commonJS((exports) => {
11143
11143
  this.emitWithAll(event, args);
11144
11144
  }
11145
11145
  };
11146
- this._awaitWriteFinish(path3, awf.stabilityThreshold, event, awfEmit);
11146
+ this._awaitWriteFinish(path4, awf.stabilityThreshold, event, awfEmit);
11147
11147
  return this;
11148
11148
  }
11149
11149
  if (event === EV_CHANGE) {
11150
- const isThrottled = !this._throttle(EV_CHANGE, path3, 50);
11150
+ const isThrottled = !this._throttle(EV_CHANGE, path4, 50);
11151
11151
  if (isThrottled)
11152
11152
  return this;
11153
11153
  }
11154
11154
  if (opts.alwaysStat && val1 === undefined && (event === EV_ADD || event === EV_ADD_DIR || event === EV_CHANGE)) {
11155
- const fullPath = opts.cwd ? sysPath.join(opts.cwd, path3) : path3;
11155
+ const fullPath = opts.cwd ? sysPath.join(opts.cwd, path4) : path4;
11156
11156
  let stats;
11157
11157
  try {
11158
11158
  stats = await stat(fullPath);
@@ -11171,21 +11171,21 @@ var require_chokidar = __commonJS((exports) => {
11171
11171
  }
11172
11172
  return error || this.closed;
11173
11173
  }
11174
- _throttle(actionType, path3, timeout) {
11174
+ _throttle(actionType, path4, timeout) {
11175
11175
  if (!this._throttled.has(actionType)) {
11176
11176
  this._throttled.set(actionType, new Map);
11177
11177
  }
11178
11178
  const action = this._throttled.get(actionType);
11179
- const actionPath = action.get(path3);
11179
+ const actionPath = action.get(path4);
11180
11180
  if (actionPath) {
11181
11181
  actionPath.count++;
11182
11182
  return false;
11183
11183
  }
11184
11184
  let timeoutObject;
11185
11185
  const clear = () => {
11186
- const item = action.get(path3);
11186
+ const item = action.get(path4);
11187
11187
  const count = item ? item.count : 0;
11188
- action.delete(path3);
11188
+ action.delete(path4);
11189
11189
  clearTimeout(timeoutObject);
11190
11190
  if (item)
11191
11191
  clearTimeout(item.timeoutObject);
@@ -11193,45 +11193,45 @@ var require_chokidar = __commonJS((exports) => {
11193
11193
  };
11194
11194
  timeoutObject = setTimeout(clear, timeout);
11195
11195
  const thr = { timeoutObject, clear, count: 0 };
11196
- action.set(path3, thr);
11196
+ action.set(path4, thr);
11197
11197
  return thr;
11198
11198
  }
11199
11199
  _incrReadyCount() {
11200
11200
  return this._readyCount++;
11201
11201
  }
11202
- _awaitWriteFinish(path3, threshold, event, awfEmit) {
11202
+ _awaitWriteFinish(path4, threshold, event, awfEmit) {
11203
11203
  let timeoutHandler;
11204
- let fullPath = path3;
11205
- if (this.options.cwd && !sysPath.isAbsolute(path3)) {
11206
- fullPath = sysPath.join(this.options.cwd, path3);
11204
+ let fullPath = path4;
11205
+ if (this.options.cwd && !sysPath.isAbsolute(path4)) {
11206
+ fullPath = sysPath.join(this.options.cwd, path4);
11207
11207
  }
11208
11208
  const now = new Date;
11209
11209
  const awaitWriteFinish = (prevStat) => {
11210
11210
  fs2.stat(fullPath, (err, curStat) => {
11211
- if (err || !this._pendingWrites.has(path3)) {
11211
+ if (err || !this._pendingWrites.has(path4)) {
11212
11212
  if (err && err.code !== "ENOENT")
11213
11213
  awfEmit(err);
11214
11214
  return;
11215
11215
  }
11216
11216
  const now2 = Number(new Date);
11217
11217
  if (prevStat && curStat.size !== prevStat.size) {
11218
- this._pendingWrites.get(path3).lastChange = now2;
11218
+ this._pendingWrites.get(path4).lastChange = now2;
11219
11219
  }
11220
- const pw = this._pendingWrites.get(path3);
11220
+ const pw = this._pendingWrites.get(path4);
11221
11221
  const df = now2 - pw.lastChange;
11222
11222
  if (df >= threshold) {
11223
- this._pendingWrites.delete(path3);
11223
+ this._pendingWrites.delete(path4);
11224
11224
  awfEmit(undefined, curStat);
11225
11225
  } else {
11226
11226
  timeoutHandler = setTimeout(awaitWriteFinish, this.options.awaitWriteFinish.pollInterval, curStat);
11227
11227
  }
11228
11228
  });
11229
11229
  };
11230
- if (!this._pendingWrites.has(path3)) {
11231
- this._pendingWrites.set(path3, {
11230
+ if (!this._pendingWrites.has(path4)) {
11231
+ this._pendingWrites.set(path4, {
11232
11232
  lastChange: now,
11233
11233
  cancelWait: () => {
11234
- this._pendingWrites.delete(path3);
11234
+ this._pendingWrites.delete(path4);
11235
11235
  clearTimeout(timeoutHandler);
11236
11236
  return event;
11237
11237
  }
@@ -11242,26 +11242,26 @@ var require_chokidar = __commonJS((exports) => {
11242
11242
  _getGlobIgnored() {
11243
11243
  return [...this._ignoredPaths.values()];
11244
11244
  }
11245
- _isIgnored(path3, stats) {
11246
- if (this.options.atomic && DOT_RE.test(path3))
11245
+ _isIgnored(path4, stats) {
11246
+ if (this.options.atomic && DOT_RE.test(path4))
11247
11247
  return true;
11248
11248
  if (!this._userIgnored) {
11249
11249
  const { cwd } = this.options;
11250
11250
  const ign = this.options.ignored;
11251
11251
  const ignored = ign && ign.map(normalizeIgnored(cwd));
11252
- const paths = arrify(ignored).filter((path4) => typeof path4 === STRING_TYPE && !isGlob(path4)).map((path4) => path4 + SLASH_GLOBSTAR);
11252
+ const paths = arrify(ignored).filter((path5) => typeof path5 === STRING_TYPE && !isGlob(path5)).map((path5) => path5 + SLASH_GLOBSTAR);
11253
11253
  const list = this._getGlobIgnored().map(normalizeIgnored(cwd)).concat(ignored, paths);
11254
11254
  this._userIgnored = anymatch(list, undefined, ANYMATCH_OPTS);
11255
11255
  }
11256
- return this._userIgnored([path3, stats]);
11256
+ return this._userIgnored([path4, stats]);
11257
11257
  }
11258
- _isntIgnored(path3, stat2) {
11259
- return !this._isIgnored(path3, stat2);
11258
+ _isntIgnored(path4, stat2) {
11259
+ return !this._isIgnored(path4, stat2);
11260
11260
  }
11261
- _getWatchHelpers(path3, depth) {
11262
- const watchPath = depth || this.options.disableGlobbing || !isGlob(path3) ? path3 : globParent(path3);
11261
+ _getWatchHelpers(path4, depth) {
11262
+ const watchPath = depth || this.options.disableGlobbing || !isGlob(path4) ? path4 : globParent(path4);
11263
11263
  const follow = this.options.followSymlinks;
11264
- return new WatchHelper(path3, watchPath, follow, this);
11264
+ return new WatchHelper(path4, watchPath, follow, this);
11265
11265
  }
11266
11266
  _getWatchedDir(directory) {
11267
11267
  if (!this._boundRemove)
@@ -11280,59 +11280,59 @@ var require_chokidar = __commonJS((exports) => {
11280
11280
  return Boolean(4 & it);
11281
11281
  }
11282
11282
  _remove(directory, item, isDirectory) {
11283
- const path3 = sysPath.join(directory, item);
11284
- const fullPath = sysPath.resolve(path3);
11285
- isDirectory = isDirectory != null ? isDirectory : this._watched.has(path3) || this._watched.has(fullPath);
11286
- if (!this._throttle("remove", path3, 100))
11283
+ const path4 = sysPath.join(directory, item);
11284
+ const fullPath = sysPath.resolve(path4);
11285
+ isDirectory = isDirectory != null ? isDirectory : this._watched.has(path4) || this._watched.has(fullPath);
11286
+ if (!this._throttle("remove", path4, 100))
11287
11287
  return;
11288
11288
  if (!isDirectory && !this.options.useFsEvents && this._watched.size === 1) {
11289
11289
  this.add(directory, item, true);
11290
11290
  }
11291
- const wp = this._getWatchedDir(path3);
11291
+ const wp = this._getWatchedDir(path4);
11292
11292
  const nestedDirectoryChildren = wp.getChildren();
11293
- nestedDirectoryChildren.forEach((nested) => this._remove(path3, nested));
11293
+ nestedDirectoryChildren.forEach((nested) => this._remove(path4, nested));
11294
11294
  const parent = this._getWatchedDir(directory);
11295
11295
  const wasTracked = parent.has(item);
11296
11296
  parent.remove(item);
11297
11297
  if (this._symlinkPaths.has(fullPath)) {
11298
11298
  this._symlinkPaths.delete(fullPath);
11299
11299
  }
11300
- let relPath = path3;
11300
+ let relPath = path4;
11301
11301
  if (this.options.cwd)
11302
- relPath = sysPath.relative(this.options.cwd, path3);
11302
+ relPath = sysPath.relative(this.options.cwd, path4);
11303
11303
  if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
11304
11304
  const event = this._pendingWrites.get(relPath).cancelWait();
11305
11305
  if (event === EV_ADD)
11306
11306
  return;
11307
11307
  }
11308
- this._watched.delete(path3);
11308
+ this._watched.delete(path4);
11309
11309
  this._watched.delete(fullPath);
11310
11310
  const eventName = isDirectory ? EV_UNLINK_DIR : EV_UNLINK;
11311
- if (wasTracked && !this._isIgnored(path3))
11312
- this._emit(eventName, path3);
11311
+ if (wasTracked && !this._isIgnored(path4))
11312
+ this._emit(eventName, path4);
11313
11313
  if (!this.options.useFsEvents) {
11314
- this._closePath(path3);
11314
+ this._closePath(path4);
11315
11315
  }
11316
11316
  }
11317
- _closePath(path3) {
11318
- this._closeFile(path3);
11319
- const dir = sysPath.dirname(path3);
11320
- this._getWatchedDir(dir).remove(sysPath.basename(path3));
11317
+ _closePath(path4) {
11318
+ this._closeFile(path4);
11319
+ const dir = sysPath.dirname(path4);
11320
+ this._getWatchedDir(dir).remove(sysPath.basename(path4));
11321
11321
  }
11322
- _closeFile(path3) {
11323
- const closers = this._closers.get(path3);
11322
+ _closeFile(path4) {
11323
+ const closers = this._closers.get(path4);
11324
11324
  if (!closers)
11325
11325
  return;
11326
11326
  closers.forEach((closer) => closer());
11327
- this._closers.delete(path3);
11327
+ this._closers.delete(path4);
11328
11328
  }
11329
- _addPathCloser(path3, closer) {
11329
+ _addPathCloser(path4, closer) {
11330
11330
  if (!closer)
11331
11331
  return;
11332
- let list = this._closers.get(path3);
11332
+ let list = this._closers.get(path4);
11333
11333
  if (!list) {
11334
11334
  list = [];
11335
- this._closers.set(path3, list);
11335
+ this._closers.set(path4, list);
11336
11336
  }
11337
11337
  list.push(closer);
11338
11338
  }
@@ -11378,7 +11378,7 @@ var require_node_loaders = __commonJS((exports, module) => {
11378
11378
  return _setPrototypeOf(o, p);
11379
11379
  }
11380
11380
  var fs2 = __require("fs");
11381
- var path3 = __require("path");
11381
+ var path4 = __require("path");
11382
11382
  var Loader = require_loader();
11383
11383
  var _require = require_precompiled_loader();
11384
11384
  var PrecompiledLoader = _require.PrecompiledLoader;
@@ -11396,7 +11396,7 @@ var require_node_loaders = __commonJS((exports, module) => {
11396
11396
  _this.noCache = !!opts.noCache;
11397
11397
  if (searchPaths) {
11398
11398
  searchPaths = Array.isArray(searchPaths) ? searchPaths : [searchPaths];
11399
- _this.searchPaths = searchPaths.map(path3.normalize);
11399
+ _this.searchPaths = searchPaths.map(path4.normalize);
11400
11400
  } else {
11401
11401
  _this.searchPaths = ["."];
11402
11402
  }
@@ -11409,7 +11409,7 @@ var require_node_loaders = __commonJS((exports, module) => {
11409
11409
  var paths = _this.searchPaths.filter(fs2.existsSync);
11410
11410
  var watcher = chokidar.watch(paths);
11411
11411
  watcher.on("all", function(event, fullname) {
11412
- fullname = path3.resolve(fullname);
11412
+ fullname = path4.resolve(fullname);
11413
11413
  if (event === "change" && fullname in _this.pathsToNames) {
11414
11414
  _this.emit("update", _this.pathsToNames[fullname], fullname);
11415
11415
  }
@@ -11425,8 +11425,8 @@ var require_node_loaders = __commonJS((exports, module) => {
11425
11425
  var fullpath = null;
11426
11426
  var paths = this.searchPaths;
11427
11427
  for (var i = 0;i < paths.length; i++) {
11428
- var basePath = path3.resolve(paths[i]);
11429
- var p = path3.resolve(paths[i], name);
11428
+ var basePath = path4.resolve(paths[i]);
11429
+ var p = path4.resolve(paths[i], name);
11430
11430
  if (p.indexOf(basePath) === 0 && fs2.existsSync(p)) {
11431
11431
  fullpath = p;
11432
11432
  break;
@@ -11675,13 +11675,13 @@ var require_globals = __commonJS((exports, module) => {
11675
11675
 
11676
11676
  // node_modules/nunjucks/src/express-app.js
11677
11677
  var require_express_app = __commonJS((exports, module) => {
11678
- var path3 = __require("path");
11678
+ var path4 = __require("path");
11679
11679
  module.exports = function express(env, app) {
11680
11680
  function NunjucksView(name, opts) {
11681
11681
  this.name = name;
11682
11682
  this.path = name;
11683
11683
  this.defaultEngine = opts.defaultEngine;
11684
- this.ext = path3.extname(name);
11684
+ this.ext = path4.extname(name);
11685
11685
  if (!this.ext && !this.defaultEngine) {
11686
11686
  throw new Error("No default engine was specified and no extension was provided.");
11687
11687
  }
@@ -12058,7 +12058,7 @@ var require_environment = __commonJS((exports, module) => {
12058
12058
  return _Obj2.apply(this, arguments) || this;
12059
12059
  }
12060
12060
  var _proto3 = Template2.prototype;
12061
- _proto3.init = function init(src, env, path3, eagerCompile) {
12061
+ _proto3.init = function init(src, env, path4, eagerCompile) {
12062
12062
  this.env = env || new Environment;
12063
12063
  if (lib.isObject(src)) {
12064
12064
  switch (src.type) {
@@ -12076,7 +12076,7 @@ var require_environment = __commonJS((exports, module) => {
12076
12076
  } else {
12077
12077
  throw new Error("src must be a string or an object describing the source");
12078
12078
  }
12079
- this.path = path3;
12079
+ this.path = path4;
12080
12080
  if (eagerCompile) {
12081
12081
  try {
12082
12082
  this._compile();
@@ -12226,7 +12226,7 @@ var require_precompile_global = __commonJS((exports, module) => {
12226
12226
  // node_modules/nunjucks/src/precompile.js
12227
12227
  var require_precompile = __commonJS((exports, module) => {
12228
12228
  var fs2 = __require("fs");
12229
- var path3 = __require("path");
12229
+ var path4 = __require("path");
12230
12230
  var _require = require_lib();
12231
12231
  var _prettifyError = _require._prettifyError;
12232
12232
  var compiler = require_compiler();
@@ -12263,8 +12263,8 @@ var require_precompile = __commonJS((exports, module) => {
12263
12263
  var templates = [];
12264
12264
  function addTemplates(dir) {
12265
12265
  fs2.readdirSync(dir).forEach(function(file) {
12266
- var filepath = path3.join(dir, file);
12267
- var subpath = filepath.substr(path3.join(input, "/").length);
12266
+ var filepath = path4.join(dir, file);
12267
+ var subpath = filepath.substr(path4.join(input, "/").length);
12268
12268
  var stat = fs2.statSync(filepath);
12269
12269
  if (stat && stat.isDirectory()) {
12270
12270
  subpath += "/";
@@ -12281,7 +12281,7 @@ var require_precompile = __commonJS((exports, module) => {
12281
12281
  } else if (pathStats.isDirectory()) {
12282
12282
  addTemplates(input);
12283
12283
  for (var i = 0;i < templates.length; i++) {
12284
- var name = templates[i].replace(path3.join(input, "/"), "");
12284
+ var name = templates[i].replace(path4.join(input, "/"), "");
12285
12285
  try {
12286
12286
  precompiled.push(_precompile(fs2.readFileSync(templates[i], "utf-8"), name, env));
12287
12287
  } catch (e) {
@@ -12653,11 +12653,11 @@ var require_nunjucks = __commonJS((exports, module) => {
12653
12653
  reset: function reset() {
12654
12654
  e = undefined;
12655
12655
  },
12656
- compile: function compile(src, env, path3, eagerCompile) {
12656
+ compile: function compile(src, env, path4, eagerCompile) {
12657
12657
  if (!e) {
12658
12658
  configure();
12659
12659
  }
12660
- return new Template(src, env, path3, eagerCompile);
12660
+ return new Template(src, env, path4, eagerCompile);
12661
12661
  },
12662
12662
  render: function render(name, ctx, cb) {
12663
12663
  if (!e) {
@@ -23258,27 +23258,27 @@ var require_util = __commonJS((exports) => {
23258
23258
  };
23259
23259
  }
23260
23260
  var normalize = lruMemoize(function normalize(aPath) {
23261
- var path4 = aPath;
23261
+ var path5 = aPath;
23262
23262
  var url = urlParse(aPath);
23263
23263
  if (url) {
23264
23264
  if (!url.path) {
23265
23265
  return aPath;
23266
23266
  }
23267
- path4 = url.path;
23267
+ path5 = url.path;
23268
23268
  }
23269
- var isAbsolute = exports.isAbsolute(path4);
23269
+ var isAbsolute = exports.isAbsolute(path5);
23270
23270
  var parts = [];
23271
23271
  var start = 0;
23272
23272
  var i = 0;
23273
23273
  while (true) {
23274
23274
  start = i;
23275
- i = path4.indexOf("/", start);
23275
+ i = path5.indexOf("/", start);
23276
23276
  if (i === -1) {
23277
- parts.push(path4.slice(start));
23277
+ parts.push(path5.slice(start));
23278
23278
  break;
23279
23279
  } else {
23280
- parts.push(path4.slice(start, i));
23281
- while (i < path4.length && path4[i] === "/") {
23280
+ parts.push(path5.slice(start, i));
23281
+ while (i < path5.length && path5[i] === "/") {
23282
23282
  i++;
23283
23283
  }
23284
23284
  }
@@ -23299,15 +23299,15 @@ var require_util = __commonJS((exports) => {
23299
23299
  }
23300
23300
  }
23301
23301
  }
23302
- path4 = parts.join("/");
23303
- if (path4 === "") {
23304
- path4 = isAbsolute ? "/" : ".";
23302
+ path5 = parts.join("/");
23303
+ if (path5 === "") {
23304
+ path5 = isAbsolute ? "/" : ".";
23305
23305
  }
23306
23306
  if (url) {
23307
- url.path = path4;
23307
+ url.path = path5;
23308
23308
  return urlGenerate(url);
23309
23309
  }
23310
- return path4;
23310
+ return path5;
23311
23311
  });
23312
23312
  exports.normalize = normalize;
23313
23313
  function join(aRoot, aPath) {
@@ -24996,11 +24996,11 @@ var require_previous_map = __commonJS((exports, module) => {
24996
24996
  this.annotation = this.getAnnotationURL(css.substring(start, end));
24997
24997
  }
24998
24998
  }
24999
- loadFile(path4) {
25000
- this.root = dirname(path4);
25001
- if (existsSync(path4)) {
25002
- this.mapFile = path4;
25003
- return readFileSync(path4, "utf-8").toString().trim();
24999
+ loadFile(path5) {
25000
+ this.root = dirname(path5);
25001
+ if (existsSync(path5)) {
25002
+ this.mapFile = path5;
25003
+ return readFileSync(path5, "utf-8").toString().trim();
25004
25004
  }
25005
25005
  }
25006
25006
  loadMap(file, prev) {
@@ -25683,9 +25683,9 @@ var require_map_generator = __commonJS((exports, module) => {
25683
25683
  if (typeof this.mapOpts.annotation === "string") {
25684
25684
  from = dirname(resolve(from, this.mapOpts.annotation));
25685
25685
  }
25686
- let path4 = relative(from, file);
25687
- this.memoizedPaths.set(file, path4);
25688
- return path4;
25686
+ let path5 = relative(from, file);
25687
+ this.memoizedPaths.set(file, path5);
25688
+ return path5;
25689
25689
  }
25690
25690
  previous() {
25691
25691
  if (!this.previousMaps) {
@@ -25741,27 +25741,27 @@ var require_map_generator = __commonJS((exports, module) => {
25741
25741
  return window.btoa(unescape(encodeURIComponent(str2)));
25742
25742
  }
25743
25743
  }
25744
- toFileUrl(path4) {
25745
- let cached = this.memoizedFileURLs.get(path4);
25744
+ toFileUrl(path5) {
25745
+ let cached = this.memoizedFileURLs.get(path5);
25746
25746
  if (cached)
25747
25747
  return cached;
25748
25748
  if (pathToFileURL) {
25749
- let fileURL = pathToFileURL(path4).toString();
25750
- this.memoizedFileURLs.set(path4, fileURL);
25749
+ let fileURL = pathToFileURL(path5).toString();
25750
+ this.memoizedFileURLs.set(path5, fileURL);
25751
25751
  return fileURL;
25752
25752
  } else {
25753
25753
  throw new Error("`map.absolute` option is not available in this PostCSS build");
25754
25754
  }
25755
25755
  }
25756
- toUrl(path4) {
25757
- let cached = this.memoizedURLs.get(path4);
25756
+ toUrl(path5) {
25757
+ let cached = this.memoizedURLs.get(path5);
25758
25758
  if (cached)
25759
25759
  return cached;
25760
25760
  if (sep === "\\") {
25761
- path4 = path4.replace(/\\/g, "/");
25761
+ path5 = path5.replace(/\\/g, "/");
25762
25762
  }
25763
- let url = encodeURI(path4).replace(/[#?]/g, encodeURIComponent);
25764
- this.memoizedURLs.set(path4, url);
25763
+ let url = encodeURI(path5).replace(/[#?]/g, encodeURIComponent);
25764
+ this.memoizedURLs.set(path5, url);
25765
25765
  return url;
25766
25766
  }
25767
25767
  }
@@ -28108,8 +28108,8 @@ var {
28108
28108
  Help
28109
28109
  } = import__.default;
28110
28110
 
28111
- // src/cli.ts
28112
- import path8 from "path";
28111
+ // src/cli/commands/css.ts
28112
+ import path3 from "path";
28113
28113
 
28114
28114
  // src/config.ts
28115
28115
  import path from "path";
@@ -28223,138 +28223,205 @@ export default function(): SiteConfig {
28223
28223
  }
28224
28224
  }
28225
28225
 
28226
- // src/server.ts
28226
+ // src/utils/css-processor.ts
28227
+ import { spawn } from "child_process";
28227
28228
  import fs from "fs";
28228
28229
  import path2 from "path";
28229
- async function startServer(outputDir = DEFAULT_OUTPUT_DIR, port = 3000) {
28230
- try {
28231
- const stats = await fs.promises.stat(outputDir);
28232
- if (!stats.isDirectory()) {
28233
- const msg = `Error: Output directory ${outputDir} does not exist or is not accessible.`;
28234
- console.error(msg);
28235
- console.log('Try running "bunki generate" first to build your site.');
28236
- throw new Error(msg);
28230
+ async function processCSS(options2) {
28231
+ const { css, projectRoot, outputDir, verbose = false } = options2;
28232
+ if (!css.enabled) {
28233
+ if (verbose) {
28234
+ console.log("CSS processing is disabled");
28237
28235
  }
28236
+ return;
28237
+ }
28238
+ const inputPath = path2.resolve(projectRoot, css.input);
28239
+ const outputPath = path2.resolve(outputDir, css.output);
28240
+ const postcssConfigPath = css.postcssConfig ? path2.resolve(projectRoot, css.postcssConfig) : path2.resolve(projectRoot, "postcss.config.js");
28241
+ try {
28242
+ await fs.promises.access(inputPath);
28238
28243
  } catch (error) {
28239
- const msg = `Error: Output directory ${outputDir} does not exist or is not accessible.`;
28240
- console.error(msg);
28241
- console.log('Try running "bunki generate" first to build your site.');
28242
- throw new Error(msg);
28244
+ throw new Error(`CSS input file not found: ${inputPath}`);
28243
28245
  }
28244
- console.log(`Starting server for site in ${outputDir}...`);
28245
- const server = Bun.serve({
28246
- port,
28247
- async fetch(req) {
28248
- try {
28249
- const url = new URL(req.url);
28250
- let pathname = url.pathname;
28251
- if (pathname === "/") {
28252
- pathname = "/index.html";
28253
- }
28254
- if (pathname.endsWith("/")) {
28255
- pathname = pathname + "index.html";
28246
+ let postcssConfigExists = false;
28247
+ try {
28248
+ await fs.promises.access(postcssConfigPath);
28249
+ postcssConfigExists = true;
28250
+ } catch (error) {
28251
+ if (verbose) {
28252
+ console.log(`PostCSS config not found at ${postcssConfigPath}, will fallback to simple copy`);
28253
+ }
28254
+ }
28255
+ const outputDirPath = path2.dirname(outputPath);
28256
+ await fs.promises.mkdir(outputDirPath, { recursive: true });
28257
+ if (verbose) {
28258
+ console.log("\uD83C\uDFA8 Building CSS with PostCSS...");
28259
+ console.log(`Input: ${inputPath}`);
28260
+ console.log(`Output: ${outputPath}`);
28261
+ console.log(`Config: ${postcssConfigPath}`);
28262
+ }
28263
+ if (!postcssConfigExists) {
28264
+ await fs.promises.copyFile(inputPath, outputPath);
28265
+ if (verbose)
28266
+ console.log("Copied CSS without PostCSS config");
28267
+ return;
28268
+ }
28269
+ const runPostCSS = (configPathToUse) => {
28270
+ return new Promise((resolve, reject) => {
28271
+ const args = ["postcss", inputPath, "-o", outputPath];
28272
+ if (configPathToUse && fs.existsSync(configPathToUse)) {
28273
+ args.push("--config", configPathToUse);
28274
+ }
28275
+ const postcss = spawn("bunx", args, {
28276
+ stdio: verbose ? "inherit" : ["ignore", "pipe", "pipe"],
28277
+ cwd: projectRoot
28278
+ });
28279
+ let errorOutput = "";
28280
+ if (!verbose) {
28281
+ postcss.stderr?.on("data", (data) => {
28282
+ errorOutput += data.toString();
28283
+ });
28284
+ }
28285
+ postcss.on("close", async (code) => {
28286
+ if (code === 0) {
28287
+ if (verbose)
28288
+ console.log("\u2705 CSS build completed successfully!");
28289
+ return resolve();
28256
28290
  }
28257
- const homePaginationMatch = pathname.match(/^\/page\/(\d+)\/?$/);
28258
- const tagPaginationMatch = pathname.match(/^\/tags\/([^\/]+)\/page\/(\d+)\/?$/);
28259
- const yearPaginationMatch = pathname.match(/^\/(\d{4})\/page\/(\d+)\/?$/);
28260
- let filePath = "";
28261
- if (homePaginationMatch) {
28262
- const pageNumber = homePaginationMatch[1];
28263
- filePath = path2.join(outputDir, "page", pageNumber, "index.html");
28264
- } else if (tagPaginationMatch) {
28265
- const tagSlug = tagPaginationMatch[1];
28266
- const pageNumber = tagPaginationMatch[2];
28267
- filePath = path2.join(outputDir, "tags", tagSlug, "page", pageNumber, "index.html");
28268
- } else if (yearPaginationMatch) {
28269
- const year = yearPaginationMatch[1];
28270
- const pageNumber = yearPaginationMatch[2];
28271
- filePath = path2.join(outputDir, year, "page", pageNumber, "index.html");
28272
- } else {
28273
- const directPath = path2.join(outputDir, pathname);
28274
- const withoutSlash = path2.join(outputDir, pathname + ".html");
28275
- const withHtml = pathname.endsWith(".html") ? directPath : withoutSlash;
28276
- const bunFileDirect = Bun.file(directPath);
28277
- const bunFileHtml = Bun.file(withHtml);
28278
- if (await bunFileDirect.exists()) {
28279
- filePath = directPath;
28280
- } else if (await bunFileHtml.exists()) {
28281
- filePath = withHtml;
28282
- } else {
28283
- const indexPath = path2.join(outputDir, pathname, "index.html");
28284
- const bunFileIndex = Bun.file(indexPath);
28285
- if (await bunFileIndex.exists()) {
28286
- filePath = indexPath;
28287
- } else {
28288
- console.log(`404 Not Found: ${pathname}`);
28289
- return new Response(`<h1>404 Not Found</h1><p>Could not find ${pathname}</p>`, {
28290
- status: 404,
28291
- headers: { "Content-Type": "text/html" }
28292
- });
28291
+ if (/module is not defined in ES module scope/i.test(errorOutput) && configPathToUse.endsWith(".js")) {
28292
+ const cjsPath = configPathToUse.replace(/\.js$/, ".cjs");
28293
+ try {
28294
+ if (!fs.existsSync(cjsPath)) {
28295
+ const original = await fs.promises.readFile(configPathToUse, "utf-8");
28296
+ await fs.promises.writeFile(cjsPath, original, "utf-8");
28297
+ if (verbose) {
28298
+ console.log(`Retrying PostCSS with converted CommonJS config at ${cjsPath}`);
28299
+ }
28293
28300
  }
28301
+ return resolve(runPostCSS(cjsPath));
28302
+ } catch (e) {
28303
+ if (verbose)
28304
+ console.warn("CJS fallback failed, copying CSS.");
28305
+ await fs.promises.copyFile(inputPath, outputPath);
28306
+ return resolve();
28294
28307
  }
28295
28308
  }
28296
- console.log(`Serving file: ${filePath}`);
28297
- const extname = path2.extname(filePath);
28298
- let contentType = "text/html";
28299
- switch (extname) {
28300
- case ".js":
28301
- contentType = "text/javascript";
28302
- break;
28303
- case ".css":
28304
- contentType = "text/css";
28305
- break;
28306
- case ".json":
28307
- contentType = "application/json";
28308
- break;
28309
- case ".png":
28310
- contentType = "image/png";
28311
- break;
28312
- case ".jpg":
28313
- case ".jpeg":
28314
- contentType = "image/jpeg";
28315
- break;
28316
- case ".svg":
28317
- contentType = "image/svg+xml";
28318
- break;
28319
- case ".xml":
28320
- contentType = "application/xml";
28321
- break;
28309
+ if (verbose) {
28310
+ console.warn(`PostCSS failed (code ${code}). Falling back to simple copy. Error: ${errorOutput.trim()}`);
28322
28311
  }
28323
28312
  try {
28324
- const bunFile = Bun.file(filePath);
28325
- return new Response(bunFile, {
28326
- headers: { "Content-Type": contentType }
28327
- });
28328
- } catch (err) {
28329
- console.error(`Error reading file ${filePath}:`, err);
28330
- return new Response(`<h1>500 Server Error</h1><p>Error reading file: ${filePath}</p><pre>${err}</pre>`, {
28331
- status: 500,
28332
- headers: { "Content-Type": "text/html" }
28333
- });
28313
+ await fs.promises.copyFile(inputPath, outputPath);
28314
+ resolve();
28315
+ } catch (copyErr) {
28316
+ reject(new Error(`CSS build failed with code ${code} and fallback copy also failed: ${copyErr.message}`));
28317
+ }
28318
+ });
28319
+ postcss.on("error", (err) => {
28320
+ if (verbose) {
28321
+ console.warn(`Failed to start PostCSS process (${err.message}). Falling back to copy.`);
28334
28322
  }
28323
+ fs.promises.copyFile(inputPath, outputPath).then(() => resolve()).catch((copyErr) => reject(new Error(`Failed to start PostCSS and fallback copy failed: ${copyErr.message}`)));
28324
+ });
28325
+ });
28326
+ };
28327
+ await runPostCSS(postcssConfigPath);
28328
+ }
28329
+ async function watchCSS(options2) {
28330
+ const { css, projectRoot, verbose = false } = options2;
28331
+ if (!css.enabled || !css.watch) {
28332
+ return;
28333
+ }
28334
+ const inputPath = path2.resolve(projectRoot, css.input);
28335
+ const watchDir = path2.dirname(inputPath);
28336
+ if (verbose) {
28337
+ console.log(`\uD83D\uDC40 Watching CSS files in ${watchDir}...`);
28338
+ }
28339
+ const watcher = fs.watch(watchDir, { recursive: true }, async (eventType, filename) => {
28340
+ if (filename && (filename.endsWith(".css") || filename.endsWith(".pcss"))) {
28341
+ if (verbose) {
28342
+ console.log(`\uD83D\uDD04 CSS file changed: ${filename}`);
28343
+ }
28344
+ try {
28345
+ await processCSS(options2);
28335
28346
  } catch (error) {
28336
- console.error("Server error:", error);
28337
- return new Response(`<h1>500 Server Error</h1><pre>${error}</pre>`, {
28338
- status: 500,
28339
- headers: { "Content-Type": "text/html" }
28340
- });
28347
+ console.error("\u274C CSS rebuild failed:", error);
28341
28348
  }
28342
28349
  }
28343
28350
  });
28344
- console.log(`Bunki development server running at http://localhost:${port}/`);
28345
- return server;
28351
+ return new Promise(() => {
28352
+ process.on("SIGINT", () => {
28353
+ watcher.close();
28354
+ process.exit(0);
28355
+ });
28356
+ });
28357
+ }
28358
+ function getDefaultCSSConfig() {
28359
+ return {
28360
+ input: "templates/styles/main.css",
28361
+ output: "css/style.css",
28362
+ postcssConfig: "postcss.config.js",
28363
+ enabled: true,
28364
+ watch: false
28365
+ };
28366
+ }
28367
+
28368
+ // src/cli/commands/css.ts
28369
+ var defaultDeps = {
28370
+ loadConfig,
28371
+ processCSS,
28372
+ watchCSS,
28373
+ getDefaultCSSConfig,
28374
+ logger: console,
28375
+ exit: (code) => process.exit(code)
28376
+ };
28377
+ async function handleCssCommand(options2, deps = defaultDeps) {
28378
+ try {
28379
+ const configPath = path3.resolve(options2.config);
28380
+ const outputDir = path3.resolve(options2.output);
28381
+ const config = await deps.loadConfig(configPath);
28382
+ const cssConfig = config.css || deps.getDefaultCSSConfig();
28383
+ if (!cssConfig.enabled) {
28384
+ deps.logger.log("CSS processing is disabled in configuration");
28385
+ return;
28386
+ }
28387
+ const processorOptions = {
28388
+ css: cssConfig,
28389
+ projectRoot: process.cwd(),
28390
+ outputDir,
28391
+ verbose: true
28392
+ };
28393
+ if (options2.watch) {
28394
+ deps.logger.log("Starting CSS watch mode...");
28395
+ cssConfig.watch = true;
28396
+ await deps.processCSS(processorOptions);
28397
+ await deps.watchCSS(processorOptions);
28398
+ } else {
28399
+ await deps.processCSS(processorOptions);
28400
+ }
28401
+ } catch (error) {
28402
+ deps.logger.error("Error processing CSS:", error);
28403
+ deps.exit(1);
28404
+ }
28346
28405
  }
28406
+ function registerCssCommand(program2) {
28407
+ return program2.command("css").description("Process CSS using PostCSS").option("-c, --config <file>", "Config file path", "bunki.config.ts").option("-o, --output <dir>", "Output directory", DEFAULT_OUTPUT_DIR).option("-w, --watch", "Watch for changes and rebuild").action(async (options2) => {
28408
+ await handleCssCommand(options2);
28409
+ });
28410
+ }
28411
+
28412
+ // src/cli/commands/generate.ts
28413
+ import path6 from "path";
28347
28414
 
28348
28415
  // src/site-generator.ts
28349
28416
  var import_nunjucks = __toESM(require_nunjucks(), 1);
28350
28417
  var import_slugify = __toESM(require_slugify(), 1);
28351
28418
  var {Glob: Glob2 } = globalThis.Bun;
28352
- import fs3 from "fs";
28419
+ import fs2 from "fs";
28353
28420
  import path5 from "path";
28354
28421
 
28355
28422
  // src/utils/file-utils.ts
28356
28423
  var {Glob } = globalThis.Bun;
28357
- import path3 from "path";
28424
+ import path4 from "path";
28358
28425
  async function findFilesByPattern(pattern, directory, absolute = true) {
28359
28426
  const glob = new Glob(pattern);
28360
28427
  const files = [];
@@ -28383,7 +28450,7 @@ async function readFileAsText(filePath) {
28383
28450
  }
28384
28451
  }
28385
28452
  function getBaseFilename(filePath, extension = ".md") {
28386
- return path3.basename(filePath, extension);
28453
+ return path4.basename(filePath, extension);
28387
28454
  }
28388
28455
  async function ensureDir(dirPath) {
28389
28456
  try {
@@ -32854,157 +32921,15 @@ async function parseMarkdownDirectory(contentDir) {
32854
32921
  }
32855
32922
  }
32856
32923
 
32857
- // src/utils/css-processor.ts
32858
- import { spawn } from "child_process";
32859
- import fs2 from "fs";
32860
- import path4 from "path";
32861
- async function processCSS(options2) {
32862
- const { css, projectRoot, outputDir, verbose = false } = options2;
32863
- if (!css.enabled) {
32864
- if (verbose) {
32865
- console.log("CSS processing is disabled");
32866
- }
32867
- return;
32868
- }
32869
- const inputPath = path4.resolve(projectRoot, css.input);
32870
- const outputPath = path4.resolve(outputDir, css.output);
32871
- const postcssConfigPath = css.postcssConfig ? path4.resolve(projectRoot, css.postcssConfig) : path4.resolve(projectRoot, "postcss.config.js");
32872
- try {
32873
- await fs2.promises.access(inputPath);
32874
- } catch (error) {
32875
- throw new Error(`CSS input file not found: ${inputPath}`);
32876
- }
32877
- let postcssConfigExists = false;
32878
- try {
32879
- await fs2.promises.access(postcssConfigPath);
32880
- postcssConfigExists = true;
32881
- } catch (error) {
32882
- if (verbose) {
32883
- console.log(`PostCSS config not found at ${postcssConfigPath}, will fallback to simple copy`);
32884
- }
32885
- }
32886
- const outputDirPath = path4.dirname(outputPath);
32887
- await fs2.promises.mkdir(outputDirPath, { recursive: true });
32888
- if (verbose) {
32889
- console.log("\uD83C\uDFA8 Building CSS with PostCSS...");
32890
- console.log(`Input: ${inputPath}`);
32891
- console.log(`Output: ${outputPath}`);
32892
- console.log(`Config: ${postcssConfigPath}`);
32893
- }
32894
- if (!postcssConfigExists) {
32895
- await fs2.promises.copyFile(inputPath, outputPath);
32896
- if (verbose)
32897
- console.log("Copied CSS without PostCSS config");
32898
- return;
32899
- }
32900
- const runPostCSS = (configPathToUse) => {
32901
- return new Promise((resolve, reject) => {
32902
- const args = ["postcss", inputPath, "-o", outputPath];
32903
- if (configPathToUse && fs2.existsSync(configPathToUse)) {
32904
- args.push("--config", configPathToUse);
32905
- }
32906
- const postcss = spawn("bunx", args, {
32907
- stdio: verbose ? "inherit" : ["ignore", "pipe", "pipe"],
32908
- cwd: projectRoot
32909
- });
32910
- let errorOutput = "";
32911
- if (!verbose) {
32912
- postcss.stderr?.on("data", (data) => {
32913
- errorOutput += data.toString();
32914
- });
32915
- }
32916
- postcss.on("close", async (code) => {
32917
- if (code === 0) {
32918
- if (verbose)
32919
- console.log("\u2705 CSS build completed successfully!");
32920
- return resolve();
32921
- }
32922
- if (/module is not defined in ES module scope/i.test(errorOutput) && configPathToUse.endsWith(".js")) {
32923
- const cjsPath = configPathToUse.replace(/\.js$/, ".cjs");
32924
- try {
32925
- if (!fs2.existsSync(cjsPath)) {
32926
- const original = await fs2.promises.readFile(configPathToUse, "utf-8");
32927
- await fs2.promises.writeFile(cjsPath, original, "utf-8");
32928
- if (verbose) {
32929
- console.log(`Retrying PostCSS with converted CommonJS config at ${cjsPath}`);
32930
- }
32931
- }
32932
- return resolve(runPostCSS(cjsPath));
32933
- } catch (e) {
32934
- if (verbose)
32935
- console.warn("CJS fallback failed, copying CSS.");
32936
- await fs2.promises.copyFile(inputPath, outputPath);
32937
- return resolve();
32938
- }
32939
- }
32940
- if (verbose) {
32941
- console.warn(`PostCSS failed (code ${code}). Falling back to simple copy. Error: ${errorOutput.trim()}`);
32942
- }
32943
- try {
32944
- await fs2.promises.copyFile(inputPath, outputPath);
32945
- resolve();
32946
- } catch (copyErr) {
32947
- reject(new Error(`CSS build failed with code ${code} and fallback copy also failed: ${copyErr.message}`));
32948
- }
32949
- });
32950
- postcss.on("error", (err) => {
32951
- if (verbose) {
32952
- console.warn(`Failed to start PostCSS process (${err.message}). Falling back to copy.`);
32953
- }
32954
- fs2.promises.copyFile(inputPath, outputPath).then(() => resolve()).catch((copyErr) => reject(new Error(`Failed to start PostCSS and fallback copy failed: ${copyErr.message}`)));
32955
- });
32956
- });
32957
- };
32958
- await runPostCSS(postcssConfigPath);
32959
- }
32960
- async function watchCSS(options2) {
32961
- const { css, projectRoot, verbose = false } = options2;
32962
- if (!css.enabled || !css.watch) {
32963
- return;
32964
- }
32965
- const inputPath = path4.resolve(projectRoot, css.input);
32966
- const watchDir = path4.dirname(inputPath);
32967
- if (verbose) {
32968
- console.log(`\uD83D\uDC40 Watching CSS files in ${watchDir}...`);
32969
- }
32970
- const watcher = fs2.watch(watchDir, { recursive: true }, async (eventType, filename) => {
32971
- if (filename && (filename.endsWith(".css") || filename.endsWith(".pcss"))) {
32972
- if (verbose) {
32973
- console.log(`\uD83D\uDD04 CSS file changed: ${filename}`);
32974
- }
32975
- try {
32976
- await processCSS(options2);
32977
- } catch (error) {
32978
- console.error("\u274C CSS rebuild failed:", error);
32979
- }
32980
- }
32981
- });
32982
- return new Promise(() => {
32983
- process.on("SIGINT", () => {
32984
- watcher.close();
32985
- process.exit(0);
32986
- });
32987
- });
32988
- }
32989
- function getDefaultCSSConfig() {
32990
- return {
32991
- input: "templates/styles/main.css",
32992
- output: "css/style.css",
32993
- postcssConfig: "postcss.config.js",
32994
- enabled: true,
32995
- watch: false
32996
- };
32997
- }
32998
-
32999
- // src/site-generator.ts
33000
- class SiteGenerator {
33001
- options;
33002
- site;
33003
- formatRSSDate(date) {
33004
- const pacificDate = new Date(new Date(date).toLocaleString("en-US", {
33005
- timeZone: "America/Los_Angeles"
33006
- }));
33007
- return pacificDate.toUTCString();
32924
+ // src/site-generator.ts
32925
+ class SiteGenerator {
32926
+ options;
32927
+ site;
32928
+ formatRSSDate(date) {
32929
+ const pacificDate = new Date(new Date(date).toLocaleString("en-US", {
32930
+ timeZone: "America/Los_Angeles"
32931
+ }));
32932
+ return pacificDate.toUTCString();
33008
32933
  }
33009
32934
  getPacificDate(date) {
33010
32935
  return new Date(new Date(date).toLocaleString("en-US", {
@@ -33288,7 +33213,7 @@ class SiteGenerator {
33288
33213
  const publicDir = path5.join(process.cwd(), "public");
33289
33214
  async function dirExists(p) {
33290
33215
  try {
33291
- const stat = await fs3.promises.stat(p);
33216
+ const stat = await fs2.promises.stat(p);
33292
33217
  return stat.isDirectory();
33293
33218
  } catch {
33294
33219
  return false;
@@ -33312,7 +33237,7 @@ class SiteGenerator {
33312
33237
  }
33313
33238
  if (await dirExists(publicDir)) {
33314
33239
  const copyRecursive = async (srcDir) => {
33315
- const entries = await fs3.promises.readdir(srcDir, {
33240
+ const entries = await fs2.promises.readdir(srcDir, {
33316
33241
  withFileTypes: true
33317
33242
  });
33318
33243
  for (const entry of entries) {
@@ -33532,12 +33457,46 @@ Sitemap: ${config.baseUrl}/sitemap.xml
33532
33457
  }
33533
33458
  }
33534
33459
 
33460
+ // src/cli/commands/generate.ts
33461
+ var defaultDeps2 = {
33462
+ loadConfig,
33463
+ createGenerator: (opts) => new SiteGenerator(opts),
33464
+ logger: console,
33465
+ exit: (code) => process.exit(code)
33466
+ };
33467
+ async function handleGenerateCommand(options2, deps = defaultDeps2) {
33468
+ try {
33469
+ const configPath = path6.resolve(options2.config);
33470
+ const contentDir = path6.resolve(options2.content);
33471
+ const outputDir = path6.resolve(options2.output);
33472
+ const templatesDir = path6.resolve(options2.templates);
33473
+ deps.logger.log("Generating site with:");
33474
+ deps.logger.log(`- Config file: ${configPath}`);
33475
+ deps.logger.log(`- Content directory: ${contentDir}`);
33476
+ deps.logger.log(`- Output directory: ${outputDir}`);
33477
+ deps.logger.log(`- Templates directory: ${templatesDir}`);
33478
+ const config = await deps.loadConfig(configPath);
33479
+ const generator = deps.createGenerator({ contentDir, outputDir, templatesDir, config });
33480
+ await generator.initialize();
33481
+ await generator.generate();
33482
+ deps.logger.log("Site generation completed successfully!");
33483
+ } catch (error) {
33484
+ deps.logger.error("Error generating site:", error);
33485
+ deps.exit(1);
33486
+ }
33487
+ }
33488
+ function registerGenerateCommand(program2) {
33489
+ return program2.command("generate").description("Generate static site from markdown content").option("-c, --config <file>", "Config file path", "bunki.config.ts").option("-d, --content <dir>", "Content directory", DEFAULT_CONTENT_DIR).option("-o, --output <dir>", "Output directory", DEFAULT_OUTPUT_DIR).option("-t, --templates <dir>", "Templates directory", DEFAULT_TEMPLATES_DIR).action(async (options2) => {
33490
+ await handleGenerateCommand(options2);
33491
+ });
33492
+ }
33493
+
33535
33494
  // src/utils/image-uploader.ts
33536
- import path7 from "path";
33495
+ import path8 from "path";
33537
33496
 
33538
33497
  // src/utils/s3-uploader.ts
33539
33498
  var {S3Client } = globalThis.Bun;
33540
- import path6 from "path";
33499
+ import path7 from "path";
33541
33500
 
33542
33501
  class S3Uploader {
33543
33502
  s3Config;
@@ -33649,18 +33608,18 @@ class S3Uploader {
33649
33608
  console.log(`Found ${imageFiles.length} images to upload`);
33650
33609
  for (const imageFile of imageFiles) {
33651
33610
  try {
33652
- const imagePath = path6.join(imagesDir, imageFile);
33653
- const filename = path6.basename(imagePath);
33654
- console.log(`[S3] Uploading image ${imagePath} to S3 bucket ${this.s3Config.bucket}/${filename}...`);
33611
+ const imagePath = path7.join(imagesDir, imageFile);
33612
+ const filename = path7.basename(imagePath);
33613
+ console.log(`[S3] Uploading image ${imagePath} to S3 bucket ${this.s3Config.bucket}/${imageFile}...`);
33655
33614
  const file = Bun.file(imagePath);
33656
33615
  const contentType = file.type;
33657
33616
  if (process.env.BUNKI_DRY_RUN === "true") {
33658
- console.log(`[S3] Dry run: would upload ${filename} with content type ${contentType}`);
33617
+ console.log(`[S3] Dry run: would upload ${imageFile} with content type ${contentType}`);
33659
33618
  } else {
33660
- const s3File = this.client.file(filename);
33619
+ const s3File = this.client.file(imageFile);
33661
33620
  await s3File.write(file);
33662
33621
  }
33663
- const imageUrl = this.getPublicUrl(filename);
33622
+ const imageUrl = this.getPublicUrl(imageFile);
33664
33623
  console.log(`[S3] Image uploaded to ${imageUrl}`);
33665
33624
  imageUrls[imageFile] = imageUrl;
33666
33625
  } catch (error) {
@@ -33680,10 +33639,10 @@ function createUploader(config) {
33680
33639
  }
33681
33640
 
33682
33641
  // src/utils/image-uploader.ts
33683
- var DEFAULT_IMAGES_DIR = path7.join(process.cwd(), "images");
33642
+ var DEFAULT_IMAGES_DIR = path8.join(process.cwd(), "images");
33684
33643
  async function uploadImages(options2 = {}) {
33685
33644
  try {
33686
- const imagesDir = path7.resolve(options2.images || DEFAULT_IMAGES_DIR);
33645
+ const imagesDir = path8.resolve(options2.images || DEFAULT_IMAGES_DIR);
33687
33646
  if (!await fileExists(imagesDir)) {
33688
33647
  console.log(`Creating images directory at ${imagesDir}...`);
33689
33648
  await ensureDir(imagesDir);
@@ -33717,7 +33676,7 @@ async function uploadImages(options2 = {}) {
33717
33676
  const uploader = createUploader(s3Config);
33718
33677
  const imageUrlMap = await uploader.uploadImages(imagesDir);
33719
33678
  if (options2.outputJson) {
33720
- const outputFile = path7.resolve(options2.outputJson);
33679
+ const outputFile = path8.resolve(options2.outputJson);
33721
33680
  await Bun.write(outputFile, JSON.stringify(imageUrlMap, null, 2));
33722
33681
  console.log(`Image URL mapping saved to ${outputFile}`);
33723
33682
  }
@@ -33737,605 +33696,750 @@ Image upload completed successfully!`);
33737
33696
  }
33738
33697
  }
33739
33698
 
33740
- // src/cli.ts
33741
- var program2 = new Command;
33742
- program2.name("bunki").description("An opinionated static site generator built with Bun").version("0.2.4");
33743
- 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) => {
33699
+ // src/cli/commands/images-push.ts
33700
+ var defaultDeps3 = {
33701
+ uploadImages,
33702
+ logger: console,
33703
+ exit: (code) => process.exit(code)
33704
+ };
33705
+ async function handleImagesPushCommand(options2, deps = defaultDeps3) {
33744
33706
  try {
33745
- const configPath = path8.resolve(options2.config);
33746
- const configCreated = await createDefaultConfig(configPath);
33747
- if (configCreated) {
33748
- console.log("Creating directory structure...");
33749
- await ensureDir(DEFAULT_CONTENT_DIR);
33750
- await ensureDir(DEFAULT_TEMPLATES_DIR);
33751
- await ensureDir(path8.join(DEFAULT_TEMPLATES_DIR, "styles"));
33752
- await ensureDir(path8.join(process.cwd(), "public"));
33753
- const templates = {
33754
- "base.njk": `<!DOCTYPE html>
33755
- <html lang="en">
33756
- <head>
33757
- <meta charset="UTF-8">
33758
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
33759
- <title>{% block title %}{{ site.title }}{% endblock %}</title>
33760
- <meta name="description" content="{% block description %}{{ site.description }}{% endblock %}">
33761
- <link rel="stylesheet" href="/css/style.css">
33762
- {% block head %}{% endblock %}
33763
- </head>
33764
- <body>
33765
- <header>
33766
- <div class="container">
33767
- <h1><a href="/">{{ site.title }}</a></h1>
33768
- <nav>
33769
- <ul>
33770
- <li><a href="/">Home</a></li>
33771
- <li><a href="/tags/">Tags</a></li>
33772
- </ul>
33773
- </nav>
33774
- </div>
33775
- </header>
33776
-
33777
- <main class="container">
33778
- {% block content %}{% endblock %}
33779
- </main>
33780
-
33781
- <footer>
33782
- <div class="container">
33783
- <p>&copy; {{ "now" | date("YYYY") }} {{ site.title }}</p>
33784
- </div>
33785
- </footer>
33786
- </body>
33787
- </html>`,
33788
- "index.njk": `{% extends "base.njk" %}
33789
-
33790
- {% block content %}
33791
- <h1>Latest Posts</h1>
33792
-
33793
- {% if posts.length > 0 %}
33794
- <div class="posts">
33795
- {% for post in posts %}
33796
- <article class="post-card">
33797
- <h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
33798
- <div class="post-meta">
33799
- <time datetime="{{ post.date }}">{{ post.date | date("MMMM D, YYYY") }}</time>
33800
- {% if post.tags.length > 0 %}
33801
- <span class="tags">
33802
- {% for tag in post.tags %}
33803
- <a href="/tags/{{ post.tagSlugs[tag] }}/">{{ tag }}</a>{% if not loop.last %}, {% endif %}
33804
- {% endfor %}
33805
- </span>
33806
- {% endif %}
33807
- </div>
33808
- <div class="post-excerpt">{{ post.excerpt }}</div>
33809
- <a href="{{ post.url }}" class="read-more">Read more \u2192</a>
33810
- </article>
33811
- {% endfor %}
33812
- </div>
33813
-
33814
- {% if pagination.totalPages > 1 %}
33815
- <nav class="pagination">
33816
- {% if pagination.hasPrevPage %}
33817
- <a href="{{ pagination.pagePath }}{% if pagination.prevPage > 1 %}page/{{ pagination.prevPage }}/{% endif %}" class="prev">\u2190 Previous</a>
33818
- {% endif %}
33819
-
33820
- {% if pagination.hasNextPage %}
33821
- <a href="{{ pagination.pagePath }}page/{{ pagination.nextPage }}/" class="next">Next \u2192</a>
33822
- {% endif %}
33823
-
33824
- <span class="page-info">Page {{ pagination.currentPage }} of {{ pagination.totalPages }}</span>
33825
- </nav>
33826
- {% endif %}
33827
- {% else %}
33828
- <p>No posts yet!</p>
33829
- {% endif %}
33830
- {% endblock %}`,
33831
- "post.njk": `{% extends "base.njk" %}
33832
-
33833
- {% block title %}{{ post.title }} | {{ site.title }}{% endblock %}
33834
- {% block description %}{{ post.excerpt }}{% endblock %}
33835
-
33836
- {% block content %}
33837
- <article class="post">
33838
- <header class="post-header">
33839
- <h1>{{ post.title }}</h1>
33840
- <div class="post-meta">
33841
- <time datetime="{{ post.date }}">{{ post.date | date("MMMM D, YYYY") }}</time>
33842
- {% if post.tags.length > 0 %}
33843
- <span class="tags">
33844
- {% for tag in post.tags %}
33845
- <a href="/tags/{{ post.tagSlugs[tag] }}/">{{ tag }}</a>{% if not loop.last %}, {% endif %}
33846
- {% endfor %}
33847
- </span>
33848
- {% endif %}
33707
+ await deps.uploadImages({
33708
+ domain: options2.domain,
33709
+ images: options2.images,
33710
+ outputJson: options2.outputJson
33711
+ });
33712
+ } catch (error) {
33713
+ deps.logger.error("Error uploading images:", error);
33714
+ deps.exit(1);
33715
+ }
33716
+ }
33717
+ function registerImagesPushCommand(program2) {
33718
+ return program2.command("images:push").description("Upload images to S3-compatible storage").option("-d, --domain <domain>", "Domain name for bucket identification (defaults to domain in bunki.config.ts)").option("-i, --images <dir>", "Images directory path", DEFAULT_IMAGES_DIR).option("--output-json <file>", "Output URL mapping to JSON file").action(async (options2) => {
33719
+ await handleImagesPushCommand(options2);
33720
+ });
33721
+ }
33722
+
33723
+ // src/cli/commands/init.ts
33724
+ import path9 from "path";
33725
+ var defaultDependencies = {
33726
+ createDefaultConfig,
33727
+ ensureDir,
33728
+ writeFile: (filePath, data) => Bun.write(filePath, data),
33729
+ logger: console,
33730
+ exit: (code) => process.exit(code)
33731
+ };
33732
+ async function handleInitCommand(options2, deps = defaultDependencies) {
33733
+ try {
33734
+ const configPath = path9.resolve(options2.config);
33735
+ const configCreated = await deps.createDefaultConfig(configPath);
33736
+ if (!configCreated) {
33737
+ deps.logger.log(`
33738
+ Skipped initialization because the config file already exists`);
33739
+ return;
33740
+ }
33741
+ deps.logger.log("Creating directory structure...");
33742
+ const baseDir = process.cwd();
33743
+ const contentDir = path9.join(baseDir, "content");
33744
+ const templatesDir = path9.join(baseDir, "templates");
33745
+ const stylesDir = path9.join(templatesDir, "styles");
33746
+ const publicDir = path9.join(baseDir, "public");
33747
+ await deps.ensureDir(contentDir);
33748
+ await deps.ensureDir(templatesDir);
33749
+ await deps.ensureDir(stylesDir);
33750
+ await deps.ensureDir(publicDir);
33751
+ for (const [filename, content] of Object.entries(getDefaultTemplates())) {
33752
+ await deps.writeFile(path9.join(templatesDir, filename), content);
33753
+ }
33754
+ await deps.writeFile(path9.join(stylesDir, "main.css"), getDefaultCss());
33755
+ await deps.writeFile(path9.join(contentDir, "welcome.md"), getSamplePost());
33756
+ deps.logger.log(`
33757
+ Initialization complete! Here are the next steps:`);
33758
+ deps.logger.log("1. Edit bunki.config.ts to configure your site");
33759
+ deps.logger.log("2. Add markdown files to the content directory");
33760
+ deps.logger.log('3. Run "bunki generate" to build your site');
33761
+ deps.logger.log('4. Run "bunki serve" to preview your site locally');
33762
+ } catch (error) {
33763
+ deps.logger.error("Error initializing site:", error);
33764
+ deps.exit(1);
33765
+ }
33766
+ }
33767
+ function registerInitCommand(program2, deps = defaultDependencies) {
33768
+ 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) => {
33769
+ await handleInitCommand(options2, deps);
33770
+ });
33771
+ }
33772
+ function getDefaultTemplates() {
33773
+ return {
33774
+ "base.njk": String.raw`<!DOCTYPE html>
33775
+ <html lang="en">
33776
+ <head>
33777
+ <meta charset="UTF-8">
33778
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
33779
+ <title>{% block title %}{{ site.title }}{% endblock %}</title>
33780
+ <meta name="description" content="{% block description %}{{ site.description }}{% endblock %}">
33781
+ <link rel="stylesheet" href="/css/style.css">
33782
+ {% block head %}{% endblock %}
33783
+ </head>
33784
+ <body>
33785
+ <header>
33786
+ <div class="container">
33787
+ <h1><a href="/">{{ site.title }}</a></h1>
33788
+ <nav>
33789
+ <ul>
33790
+ <li><a href="/">Home</a></li>
33791
+ <li><a href="/tags/">Tags</a></li>
33792
+ </ul>
33793
+ </nav>
33849
33794
  </div>
33850
33795
  </header>
33851
33796
 
33852
- <div class="post-content">
33853
- {{ post.html | safe }}
33854
- </div>
33855
- </article>
33856
- {% endblock %}`,
33857
- "tag.njk": `{% extends "base.njk" %}
33858
-
33859
- {% block title %}{{ tag.name }} | {{ site.title }}{% endblock %}
33860
- {% block description %}Posts tagged with {{ tag.name }} on {{ site.title }}{% endblock %}
33861
-
33862
- {% block content %}
33863
- <h1>Posts tagged "{{ tag.name }}"</h1>
33864
-
33865
- {% if tag.description %}
33866
- <div class="tag-description">{{ tag.description }}</div>
33867
- {% endif %}
33868
-
33869
- {% if tag.posts.length > 0 %}
33870
- <div class="posts">
33871
- {% for post in tag.posts %}
33872
- <article class="post-card">
33873
- <h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
33874
- <div class="post-meta">
33875
- <time datetime="{{ post.date }}">{{ post.date | date("MMMM D, YYYY") }}</time>
33876
- </div>
33877
- <div class="post-excerpt">{{ post.excerpt }}</div>
33878
- <a href="{{ post.url }}" class="read-more">Read more \u2192</a>
33879
- </article>
33880
- {% endfor %}
33881
- </div>
33882
-
33883
- {% if pagination.totalPages > 1 %}
33884
- <nav class="pagination">
33885
- {% if pagination.hasPrevPage %}
33886
- <a href="{{ pagination.pagePath }}{% if pagination.prevPage > 1 %}page/{{ pagination.prevPage }}/{% endif %}" class="prev">\u2190 Previous</a>
33887
- {% endif %}
33888
-
33889
- {% if pagination.hasNextPage %}
33890
- <a href="{{ pagination.pagePath }}page/{{ pagination.nextPage }}/" class="next">Next \u2192</a>
33891
- {% endif %}
33892
-
33893
- <span class="page-info">Page {{ pagination.currentPage }} of {{ pagination.totalPages }}</span>
33894
- </nav>
33797
+ <main class="container">
33798
+ {% block content %}{% endblock %}
33799
+ </main>
33800
+
33801
+ <footer>
33802
+ <div class="container">
33803
+ <p>&copy; {{ "now" | date("YYYY") }} {{ site.title }}</p>
33804
+ </div>
33805
+ </footer>
33806
+ </body>
33807
+ </html>`,
33808
+ "index.njk": String.raw`{% extends "base.njk" %}
33809
+
33810
+ {% block content %}
33811
+ <h1>Latest Posts</h1>
33812
+
33813
+ {% if posts.length > 0 %}
33814
+ <div class="posts">
33815
+ {% for post in posts %}
33816
+ <article class="post-card">
33817
+ <h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
33818
+ <div class="post-meta">
33819
+ <time datetime="{{ post.date }}">{{ post.date | date("MMMM D, YYYY") }}</time>
33820
+ {% if post.tags.length > 0 %}
33821
+ <span class="tags">
33822
+ {% for tag in post.tags %}
33823
+ <a href="/tags/{{ post.tagSlugs[tag] }}/">{{ tag }}</a>{% if not loop.last %}, {% endif %}
33824
+ {% endfor %}
33825
+ </span>
33826
+ {% endif %}
33827
+ </div>
33828
+ <div class="post-excerpt">{{ post.excerpt }}</div>
33829
+ <a href="{{ post.url }}" class="read-more">Read more \u2192</a>
33830
+ </article>
33831
+ {% endfor %}
33832
+ </div>
33833
+
33834
+ {% if pagination.totalPages > 1 %}
33835
+ <nav class="pagination">
33836
+ {% if pagination.hasPrevPage %}
33837
+ <a href="{{ pagination.pagePath }}{% if pagination.prevPage > 1 %}page/{{ pagination.prevPage }}/{% endif %}" class="prev">\u2190 Previous</a>
33838
+ {% endif %}
33839
+
33840
+ {% if pagination.hasNextPage %}
33841
+ <a href="{{ pagination.pagePath }}page/{{ pagination.nextPage }}/" class="next">Next \u2192</a>
33842
+ {% endif %}
33843
+
33844
+ <span class="page-info">Page {{ pagination.currentPage }} of {{ pagination.totalPages }}</span>
33845
+ </nav>
33846
+ {% endif %}
33847
+ {% else %}
33848
+ <p>No posts yet!</p>
33895
33849
  {% endif %}
33896
- {% else %}
33897
- <p>No posts with this tag yet!</p>
33898
- {% endif %}
33899
- {% endblock %}`,
33900
- "tags.njk": `{% extends "base.njk" %}
33901
-
33902
- {% block title %}Tags | {{ site.title }}{% endblock %}
33903
- {% block description %}Browse all tags on {{ site.title }}{% endblock %}
33904
-
33905
- {% block content %}
33906
- <h1>All Tags</h1>
33907
-
33908
- {% if tags.length > 0 %}
33909
- <ul class="tags-list">
33910
- {% for tag in tags %}
33911
- <li>
33912
- <a href="/tags/{{ tag.slug }}/">{{ tag.name }}</a>
33913
- <span class="count">({{ tag.count }})</span>
33914
- {% if tag.description %}
33915
- <p class="description">{{ tag.description }}</p>
33850
+ {% endblock %}`,
33851
+ "post.njk": String.raw`{% extends "base.njk" %}
33852
+
33853
+ {% block title %}{{ post.title }} | {{ site.title }}{% endblock %}
33854
+ {% block description %}{{ post.excerpt }}{% endblock %}
33855
+
33856
+ {% block content %}
33857
+ <article class="post">
33858
+ <header class="post-header">
33859
+ <h1>{{ post.title }}</h1>
33860
+ <div class="post-meta">
33861
+ <time datetime="{{ post.date }}">{{ post.date | date("MMMM D, YYYY") }}</time>
33862
+ {% if post.tags.length > 0 %}
33863
+ <span class="tags">
33864
+ {% for tag in post.tags %}
33865
+ <a href="/tags/{{ post.tagSlugs[tag] }}/">{{ tag }}</a>{% if not loop.last %}, {% endif %}
33866
+ {% endfor %}
33867
+ </span>
33916
33868
  {% endif %}
33917
- </li>
33918
- {% endfor %}
33919
- </ul>
33920
- {% else %}
33921
- <p>No tags found!</p>
33922
- {% endif %}
33923
- {% endblock %}`,
33924
- "archive.njk": `{% extends "base.njk" %}
33925
-
33926
- {% block title %}Archive {{ year }} | {{ site.title }}{% endblock %}
33927
- {% block description %}Posts from {{ year }} on {{ site.title }}{% endblock %}
33928
-
33929
- {% block content %}
33930
- <h1>Posts from {{ year }}</h1>
33931
-
33932
- {% if posts.length > 0 %}
33933
- <div class="posts">
33934
- {% for post in posts %}
33935
- <article class="post-card">
33936
- <h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
33937
- <div class="post-meta">
33938
- <time datetime="{{ post.date }}">{{ post.date | date("MMMM D, YYYY") }}</time>
33939
- {% if post.tags.length > 0 %}
33940
- <span class="tags">
33941
- {% for tag in post.tags %}
33942
- <a href="/tags/{{ post.tagSlugs[tag] }}/">{{ tag }}</a>{% if not loop.last %}, {% endif %}
33943
- {% endfor %}
33944
- </span>
33869
+ </div>
33870
+ </header>
33871
+
33872
+ <div class="post-content">
33873
+ {{ post.html | safe }}
33874
+ </div>
33875
+ </article>
33876
+ {% endblock %}`,
33877
+ "tag.njk": String.raw`{% extends "base.njk" %}
33878
+
33879
+ {% block title %}{{ tag.name }} | {{ site.title }}{% endblock %}
33880
+ {% block description %}Posts tagged with {{ tag.name }} on {{ site.title }}{% endblock %}
33881
+
33882
+ {% block content %}
33883
+ <h1>Posts tagged "{{ tag.name }}"</h1>
33884
+
33885
+ {% if tag.description %}
33886
+ <div class="tag-description">{{ tag.description }}</div>
33887
+ {% endif %}
33888
+
33889
+ {% if tag.posts.length > 0 %}
33890
+ <div class="posts">
33891
+ {% for post in tag.posts %}
33892
+ <article class="post-card">
33893
+ <h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
33894
+ <div class="post-meta">
33895
+ <time datetime="{{ post.date }}">{{ post.date | date("MMMM D, YYYY") }}</time>
33896
+ </div>
33897
+ <div class="post-excerpt">{{ post.excerpt }}</div>
33898
+ <a href="{{ post.url }}" class="read-more">Read more \u2192</a>
33899
+ </article>
33900
+ {% endfor %}
33901
+ </div>
33902
+
33903
+ {% if pagination.totalPages > 1 %}
33904
+ <nav class="pagination">
33905
+ {% if pagination.hasPrevPage %}
33906
+ <a href="{{ pagination.pagePath }}{% if pagination.prevPage > 1 %}page/{{ pagination.prevPage }}/{% endif %}" class="prev">\u2190 Previous</a>
33907
+ {% endif %}
33908
+
33909
+ {% if pagination.hasNextPage %}
33910
+ <a href="{{ pagination.pagePath }}page/{{ pagination.nextPage }}/" class="next">Next \u2192</a>
33911
+ {% endif %}
33912
+
33913
+ <span class="page-info">Page {{ pagination.currentPage }} of {{ pagination.totalPages }}</span>
33914
+ </nav>
33915
+ {% endif %}
33916
+ {% else %}
33917
+ <p>No posts with this tag yet!</p>
33918
+ {% endif %}
33919
+ {% endblock %}`,
33920
+ "tags.njk": String.raw`{% extends "base.njk" %}
33921
+
33922
+ {% block title %}Tags | {{ site.title }}{% endblock %}
33923
+ {% block description %}Browse all tags on {{ site.title }}{% endblock %}
33924
+
33925
+ {% block content %}
33926
+ <h1>All Tags</h1>
33927
+
33928
+ {% if tags.length > 0 %}
33929
+ <ul class="tags-list">
33930
+ {% for tag in tags %}
33931
+ <li>
33932
+ <a href="/tags/{{ tag.slug }}/">{{ tag.name }}</a>
33933
+ <span class="count">({{ tag.count }})</span>
33934
+ {% if tag.description %}
33935
+ <p class="description">{{ tag.description }}</p>
33945
33936
  {% endif %}
33946
- </div>
33947
- <div class="post-excerpt">{{ post.excerpt }}</div>
33948
- <a href="{{ post.url }}" class="read-more">Read more \u2192</a>
33949
- </article>
33950
- {% endfor %}
33951
- </div>
33952
-
33953
- {% if pagination.totalPages > 1 %}
33954
- <nav class="pagination">
33955
- {% if pagination.hasPrevPage %}
33956
- <a href="/{{ year }}/{% if pagination.prevPage > 1 %}page/{{ pagination.prevPage }}/{% endif %}" class="prev">\u2190 Previous</a>
33957
- {% endif %}
33958
-
33959
- {% if pagination.hasNextPage %}
33960
- <a href="/{{ year }}/page/{{ pagination.nextPage }}/" class="next">Next \u2192</a>
33961
- {% endif %}
33962
-
33963
- <span class="page-info">Page {{ pagination.currentPage }} of {{ pagination.totalPages }}</span>
33964
- </nav>
33937
+ </li>
33938
+ {% endfor %}
33939
+ </ul>
33940
+ {% else %}
33941
+ <p>No tags found!</p>
33965
33942
  {% endif %}
33966
- {% else %}
33967
- <p>No posts from {{ year }}!</p>
33968
- {% endif %}
33969
- {% endblock %}`
33970
- };
33971
- for (const [filename, content] of Object.entries(templates)) {
33972
- await Bun.write(path8.join(DEFAULT_TEMPLATES_DIR, filename), content);
33973
- }
33974
- const defaultCss = `/* Reset & base styles */
33975
- * {
33976
- margin: 0;
33977
- padding: 0;
33978
- box-sizing: border-box;
33979
- }
33943
+ {% endblock %}`,
33944
+ "archive.njk": String.raw`{% extends "base.njk" %}
33945
+
33946
+ {% block title %}Archive {{ year }} | {{ site.title }}{% endblock %}
33947
+ {% block description %}Posts from {{ year }} on {{ site.title }}{% endblock %}
33948
+
33949
+ {% block content %}
33950
+ <h1>Posts from {{ year }}</h1>
33951
+
33952
+ {% if posts.length > 0 %}
33953
+ <div class="posts">
33954
+ {% for post in posts %}
33955
+ <article class="post-card">
33956
+ <h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
33957
+ <div class="post-meta">
33958
+ <time datetime="{{ post.date }}">{{ post.date | date("MMMM D, YYYY") }}</time>
33959
+ {% if post.tags.length > 0 %}
33960
+ <span class="tags">
33961
+ {% for tag in post.tags %}
33962
+ <a href="/tags/{{ post.tagSlugs[tag] }}/">{{ tag }}</a>{% if not loop.last %}, {% endif %}
33963
+ {% endfor %}
33964
+ </span>
33965
+ {% endif %}
33966
+ </div>
33967
+ <div class="post-excerpt">{{ post.excerpt }}</div>
33968
+ <a href="{{ post.url }}" class="read-more">Read more \u2192</a>
33969
+ </article>
33970
+ {% endfor %}
33971
+ </div>
33980
33972
 
33981
- body {
33982
- font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
33983
- line-height: 1.6;
33984
- color: #333;
33985
- background-color: #f8f9fa;
33986
- padding-bottom: 2rem;
33987
- }
33973
+ {% if pagination.totalPages > 1 %}
33974
+ <nav class="pagination">
33975
+ {% if pagination.hasPrevPage %}
33976
+ <a href="/{{ year }}/{% if pagination.prevPage > 1 %}page/{{ pagination.prevPage }}/{% endif %}" class="prev">\u2190 Previous</a>
33977
+ {% endif %}
33988
33978
 
33989
- a {
33990
- color: #0066cc;
33991
- text-decoration: none;
33992
- }
33979
+ {% if pagination.hasNextPage %}
33980
+ <a href="/{{ year }}/page/{{ pagination.nextPage }}/" class="next">Next \u2192</a>
33981
+ {% endif %}
33993
33982
 
33994
- a:hover {
33995
- text-decoration: underline;
33983
+ <span class="page-info">Page {{ pagination.currentPage }} of {{ pagination.totalPages }}</span>
33984
+ </nav>
33985
+ {% endif %}
33986
+ {% else %}
33987
+ <p>No posts from {{ year }}!</p>
33988
+ {% endif %}
33989
+ {% endblock %}`
33990
+ };
33996
33991
  }
33992
+ function getDefaultCss() {
33993
+ return String.raw`/* Reset & base styles */
33994
+ * {
33995
+ margin: 0;
33996
+ padding: 0;
33997
+ box-sizing: border-box;
33998
+ }
33997
33999
 
33998
- .container {
33999
- max-width: 800px;
34000
- margin: 0 auto;
34001
- padding: 0 1.5rem;
34002
- }
34000
+ body {
34001
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
34002
+ line-height: 1.6;
34003
+ color: #333;
34004
+ background-color: #f8f9fa;
34005
+ padding-bottom: 2rem;
34006
+ }
34003
34007
 
34004
- /* Header */
34005
- header {
34006
- background-color: #fff;
34007
- padding: 1.5rem 0;
34008
- box-shadow: 0 1px 3px rgba(0,0,0,0.1);
34009
- margin-bottom: 2rem;
34010
- }
34008
+ a {
34009
+ color: #0066cc;
34010
+ text-decoration: none;
34011
+ }
34011
34012
 
34012
- header h1 {
34013
- font-size: 1.8rem;
34014
- margin: 0;
34015
- }
34013
+ a:hover {
34014
+ text-decoration: underline;
34015
+ }
34016
34016
 
34017
- header h1 a {
34018
- color: #333;
34019
- text-decoration: none;
34020
- }
34017
+ .container {
34018
+ max-width: 800px;
34019
+ margin: 0 auto;
34020
+ padding: 0 1.5rem;
34021
+ }
34021
34022
 
34022
- header nav {
34023
- margin-top: 0.5rem;
34024
- }
34023
+ /* Header */
34024
+ header {
34025
+ background-color: #fff;
34026
+ padding: 1.5rem 0;
34027
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1);
34028
+ margin-bottom: 2rem;
34029
+ }
34025
34030
 
34026
- header nav ul {
34027
- display: flex;
34028
- list-style: none;
34029
- gap: 1.5rem;
34030
- }
34031
+ header h1 {
34032
+ font-size: 1.8rem;
34033
+ margin: 0;
34034
+ }
34031
34035
 
34032
- /* Main content */
34033
- main {
34034
- background-color: #fff;
34035
- padding: 2rem;
34036
- border-radius: 5px;
34037
- box-shadow: 0 1px 3px rgba(0,0,0,0.1);
34038
- }
34036
+ header h1 a {
34037
+ color: #333;
34038
+ text-decoration: none;
34039
+ }
34039
34040
 
34040
- /* Posts */
34041
- .posts {
34042
- display: flex;
34043
- flex-direction: column;
34044
- gap: 2rem;
34045
- }
34041
+ header nav {
34042
+ margin-top: 0.5rem;
34043
+ }
34046
34044
 
34047
- .post-card {
34048
- border-bottom: 1px solid #eee;
34049
- padding-bottom: 1.5rem;
34050
- }
34045
+ header nav ul {
34046
+ display: flex;
34047
+ list-style: none;
34048
+ gap: 1.5rem;
34049
+ }
34051
34050
 
34052
- .post-card:last-child {
34053
- border-bottom: none;
34054
- }
34051
+ /* Main content */
34052
+ main {
34053
+ background-color: #fff;
34054
+ padding: 2rem;
34055
+ border-radius: 5px;
34056
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1);
34057
+ }
34055
34058
 
34056
- .post-card h2 {
34057
- margin-bottom: 0.5rem;
34058
- }
34059
+ /* Posts */
34060
+ .posts {
34061
+ display: flex;
34062
+ flex-direction: column;
34063
+ gap: 2rem;
34064
+ }
34059
34065
 
34060
- .post-meta {
34061
- font-size: 0.9rem;
34062
- color: #6c757d;
34063
- margin-bottom: 1rem;
34064
- }
34066
+ .post-card {
34067
+ border-bottom: 1px solid #eee;
34068
+ padding-bottom: 1.5rem;
34069
+ }
34065
34070
 
34066
- .post-excerpt {
34067
- margin-bottom: 1rem;
34068
- }
34071
+ .post-card:last-child {
34072
+ border-bottom: none;
34073
+ }
34069
34074
 
34070
- .read-more {
34071
- font-weight: 500;
34072
- }
34075
+ .post-card h2 {
34076
+ margin-bottom: 0.5rem;
34077
+ }
34073
34078
 
34074
- /* Single post */
34075
- .post-header {
34076
- margin-bottom: 2rem;
34077
- }
34079
+ .post-meta {
34080
+ font-size: 0.9rem;
34081
+ color: #6c757d;
34082
+ margin-bottom: 1rem;
34083
+ }
34078
34084
 
34079
- .post-content {
34080
- line-height: 1.8;
34081
- }
34085
+ .post-excerpt {
34086
+ margin-bottom: 1rem;
34087
+ }
34082
34088
 
34083
- .post-content p,
34084
- .post-content ul,
34085
- .post-content ol,
34086
- .post-content blockquote {
34087
- margin-bottom: 1.5rem;
34088
- }
34089
+ .read-more {
34090
+ font-weight: 500;
34091
+ }
34089
34092
 
34090
- .post-content h2,
34091
- .post-content h3,
34092
- .post-content h4 {
34093
- margin-top: 2rem;
34094
- margin-bottom: 1rem;
34095
- }
34093
+ /* Single post */
34094
+ .post-header {
34095
+ margin-bottom: 2rem;
34096
+ }
34096
34097
 
34097
- .post-content img {
34098
- max-width: 100%;
34099
- height: auto;
34100
- display: block;
34101
- margin: 2rem auto;
34102
- }
34098
+ .post-content {
34099
+ line-height: 1.8;
34100
+ }
34103
34101
 
34104
- .post-content pre {
34105
- background-color: #f5f5f5;
34106
- padding: 1rem;
34107
- border-radius: 4px;
34108
- overflow-x: auto;
34109
- margin-bottom: 1.5rem;
34110
- }
34102
+ .post-content p,
34103
+ .post-content ul,
34104
+ .post-content ol,
34105
+ .post-content blockquote {
34106
+ margin-bottom: 1.5rem;
34107
+ }
34111
34108
 
34112
- .post-content code {
34113
- font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
34114
- font-size: 0.9em;
34115
- background-color: #f5f5f5;
34116
- padding: 0.2em 0.4em;
34117
- border-radius: 3px;
34118
- }
34109
+ .post-content h2,
34110
+ .post-content h3,
34111
+ .post-content h4 {
34112
+ margin-top: 2rem;
34113
+ margin-bottom: 1rem;
34114
+ }
34119
34115
 
34120
- .post-content pre code {
34121
- padding: 0;
34122
- background-color: transparent;
34123
- }
34116
+ .post-content img {
34117
+ max-width: 100%;
34118
+ height: auto;
34119
+ display: block;
34120
+ margin: 2rem auto;
34121
+ }
34124
34122
 
34125
- /* Tags */
34126
- .tags a {
34127
- display: inline-block;
34128
- margin-left: 0.5rem;
34129
- }
34123
+ .post-content pre {
34124
+ background-color: #f5f5f5;
34125
+ padding: 1rem;
34126
+ border-radius: 4px;
34127
+ overflow-x: auto;
34128
+ margin-bottom: 1.5rem;
34129
+ }
34130
34130
 
34131
- .tags-list {
34132
- list-style: none;
34133
- }
34131
+ .post-content code {
34132
+ font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
34133
+ font-size: 0.9em;
34134
+ background-color: #f5f5f5;
34135
+ padding: 0.2em 0.4em;
34136
+ border-radius: 3px;
34137
+ }
34134
34138
 
34135
- .tags-list li {
34136
- margin-bottom: 1rem;
34137
- }
34139
+ .post-content pre code {
34140
+ padding: 0;
34141
+ background-color: transparent;
34142
+ }
34138
34143
 
34139
- .tags-list .count {
34140
- color: #6c757d;
34141
- font-size: 0.9rem;
34142
- }
34144
+ /* Tags */
34145
+ .tags a {
34146
+ display: inline-block;
34147
+ margin-left: 0.5rem;
34148
+ }
34143
34149
 
34144
- .tags-list .description {
34145
- margin-top: 0.25rem;
34146
- font-size: 0.9rem;
34147
- color: #6c757d;
34148
- }
34150
+ .tags-list {
34151
+ list-style: none;
34152
+ }
34149
34153
 
34150
- /* Pagination */
34151
- .pagination {
34152
- display: flex;
34153
- justify-content: space-between;
34154
- align-items: center;
34155
- margin-top: 2rem;
34156
- padding-top: 1rem;
34157
- border-top: 1px solid #eee;
34158
- }
34154
+ .tags-list li {
34155
+ margin-bottom: 1rem;
34156
+ }
34159
34157
 
34160
- .pagination .page-info {
34161
- color: #6c757d;
34162
- font-size: 0.9rem;
34163
- }
34158
+ .tags-list .count {
34159
+ color: #6c757d;
34160
+ font-size: 0.9rem;
34161
+ }
34164
34162
 
34165
- /* Footer */
34166
- footer {
34167
- text-align: center;
34168
- padding: 2rem 0;
34169
- color: #6c757d;
34170
- font-size: 0.9rem;
34171
- }`;
34172
- await Bun.write(path8.join(DEFAULT_TEMPLATES_DIR, "styles", "main.css"), defaultCss);
34173
- const samplePost = `---
34174
- title: Welcome to Bunki
34175
- date: ${new Date().toISOString()}
34176
- tags: [getting-started, bunki]
34177
- ---
34163
+ .tags-list .description {
34164
+ margin-top: 0.25rem;
34165
+ font-size: 0.9rem;
34166
+ color: #6c757d;
34167
+ }
34178
34168
 
34179
- # Welcome to Your New Bunki Site
34169
+ /* Pagination */
34170
+ .pagination {
34171
+ display: flex;
34172
+ justify-content: space-between;
34173
+ align-items: center;
34174
+ margin-top: 2rem;
34175
+ padding-top: 1rem;
34176
+ border-top: 1px solid #eee;
34177
+ }
34180
34178
 
34181
- This is a sample blog post to help you get started with Bunki. You can edit this file or create new markdown files in the \`content\` directory.
34179
+ .pagination .page-info {
34180
+ color: #6c757d;
34181
+ font-size: 0.9rem;
34182
+ }
34182
34183
 
34183
- ## Features
34184
+ /* Footer */
34185
+ footer {
34186
+ text-align: center;
34187
+ padding: 2rem 0;
34188
+ color: #6c757d;
34189
+ font-size: 0.9rem;
34190
+ }`;
34191
+ }
34192
+ function getSamplePost() {
34193
+ return `---
34194
+ title: Welcome to Bunki
34195
+ date: ${new Date().toISOString()}
34196
+ tags: [getting-started, bunki]
34197
+ ---
34184
34198
 
34185
- - Markdown support with frontmatter
34186
- - Syntax highlighting for code blocks
34187
- - Tag-based organization
34188
- - Pagination for post listings
34189
- - RSS feed generation
34190
- - Sitemap generation
34199
+ # Welcome to Your New Bunki Site
34191
34200
 
34192
- ## Adding Content
34201
+ This is a sample blog post to help you get started with Bunki. You can edit this file or create new markdown files in the \`content\` directory.
34193
34202
 
34194
- Create new markdown files in the \`content\` directory with frontmatter like this:
34203
+ ## Features
34195
34204
 
34196
- \`\`\`markdown
34197
- ---
34198
- title: Your Post Title
34199
- date: 2025-01-01T12:00:00Z
34200
- tags: [tag1, tag2]
34201
- ---
34205
+ - Markdown support with frontmatter
34206
+ - Syntax highlighting for code blocks
34207
+ - Tag-based organization
34208
+ - Pagination for post listings
34209
+ - RSS feed generation
34210
+ - Sitemap generation
34202
34211
 
34203
- Your post content goes here...
34204
- \`\`\`
34212
+ ## Adding Content
34205
34213
 
34206
- ## Code Highlighting
34214
+ Create new markdown files in the \`content\` directory with frontmatter like this:
34207
34215
 
34208
- Bunki supports syntax highlighting for code blocks:
34216
+ \`\`\`markdown
34217
+ ---
34218
+ title: Your Post Title
34219
+ date: 2025-01-01T12:00:00Z
34220
+ tags: [tag1, tag2]
34221
+ ---
34209
34222
 
34210
- \`\`\`javascript
34211
- function hello() {
34212
- console.log('Hello, world!');
34213
- }
34214
- \`\`\`
34223
+ Your post content goes here...
34224
+ \`\`\`
34215
34225
 
34216
- ## Next Steps
34226
+ ## Code Highlighting
34217
34227
 
34218
- 1. Edit the site configuration in \`bunki.config.ts\`
34219
- 2. Create your own templates in the \`templates\` directory
34220
- 3. Add more blog posts in the \`content\` directory
34221
- 4. Run \`bunki generate\` to build your site
34222
- 5. Run \`bunki serve\` to preview your site locally
34223
- `;
34224
- await Bun.write(path8.join(DEFAULT_CONTENT_DIR, "welcome.md"), samplePost);
34225
- console.log(`
34226
- Initialization complete! Here are the next steps:`);
34227
- console.log("1. Edit bunki.config.ts to configure your site");
34228
- console.log("2. Add markdown files to the content directory");
34229
- console.log('3. Run "bunki generate" to build your site');
34230
- console.log('4. Run "bunki serve" to preview your site locally');
34231
- } else {
34232
- console.log(`
34233
- Skipped initialization because the config file already exists`);
34234
- }
34235
- } catch (error) {
34236
- console.error("Error initializing site:", error);
34237
- process.exit(1);
34228
+ Bunki supports syntax highlighting for code blocks:
34229
+
34230
+ \`\`\`javascript
34231
+ function hello() {
34232
+ console.log('Hello, world!');
34238
34233
  }
34239
- });
34240
- program2.command("new").description("Create a new blog post").argument("<title>", "Title of the post").option("-t, --tags <tags>", "Comma-separated list of tags", "").action(async (title, options2) => {
34234
+ \`\`\`
34235
+
34236
+ ## Next Steps
34237
+
34238
+ 1. Edit the site configuration in \`bunki.config.ts\`
34239
+ 2. Create your own templates in the \`templates\` directory
34240
+ 3. Add more blog posts in the \`content\` directory
34241
+ 4. Run \`bunki generate\` to build your site
34242
+ 5. Run \`bunki serve\` to preview your site locally
34243
+ `;
34244
+ }
34245
+
34246
+ // src/cli/commands/new-post.ts
34247
+ import path10 from "path";
34248
+ var defaultDeps4 = {
34249
+ writeFile: (filePath, data) => Bun.write(filePath, data),
34250
+ now: () => new Date,
34251
+ logger: console,
34252
+ exit: (code) => process.exit(code)
34253
+ };
34254
+ function createSlug(title) {
34255
+ return title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
34256
+ }
34257
+ async function handleNewCommand(title, options2, deps = defaultDeps4) {
34241
34258
  try {
34242
- const slug = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
34243
- const date = new Date().toISOString();
34244
- const tags = options2.tags ? options2.tags.split(",").map((tag) => tag.trim()) : [];
34259
+ const slug = createSlug(title);
34260
+ const date = deps.now().toISOString();
34261
+ const tags = options2.tags ? options2.tags.split(",").map((tag) => tag.trim()).filter(Boolean) : [];
34245
34262
  const frontmatter = `---
34246
- title: ${title}
34247
- date: ${date}
34248
- tags: [${tags.join(", ")}]
34249
- ---
34263
+ ` + `title: ${title}
34264
+ ` + `date: ${date}
34265
+ ` + `tags: [${tags.join(", ")}]
34266
+ ` + `---
34250
34267
 
34251
- # ${title}
34268
+ ` + `# ${title}
34252
34269
 
34253
34270
  `;
34254
- const filePath = path8.join(DEFAULT_CONTENT_DIR, `${slug}.md`);
34255
- await Bun.write(filePath, frontmatter);
34256
- console.log(`Created new post: ${filePath}`);
34257
- } catch (error) {
34258
- console.error("Error creating new post:", error);
34259
- process.exit(1);
34260
- }
34261
- });
34262
- program2.command("generate").description("Generate static site from markdown content").option("-c, --config <file>", "Config file path", "bunki.config.ts").option("-d, --content <dir>", "Content directory", DEFAULT_CONTENT_DIR).option("-o, --output <dir>", "Output directory", DEFAULT_OUTPUT_DIR).option("-t, --templates <dir>", "Templates directory", DEFAULT_TEMPLATES_DIR).action(async (options2) => {
34263
- try {
34264
- const configPath = path8.resolve(options2.config);
34265
- const contentDir = path8.resolve(options2.content);
34266
- const outputDir = path8.resolve(options2.output);
34267
- const templatesDir = path8.resolve(options2.templates);
34268
- console.log("Generating site with:");
34269
- console.log(`- Config file: ${configPath}`);
34270
- console.log(`- Content directory: ${contentDir}`);
34271
- console.log(`- Output directory: ${outputDir}`);
34272
- console.log(`- Templates directory: ${templatesDir}`);
34273
- const config = await loadConfig(configPath);
34274
- const generator = new SiteGenerator({
34275
- contentDir,
34276
- outputDir,
34277
- templatesDir,
34278
- config
34279
- });
34280
- await generator.initialize();
34281
- await generator.generate();
34282
- console.log("Site generation completed successfully!");
34271
+ const filePath = path10.join(DEFAULT_CONTENT_DIR, `${slug}.md`);
34272
+ await deps.writeFile(filePath, frontmatter);
34273
+ deps.logger.log(`Created new post: ${filePath}`);
34274
+ return filePath;
34283
34275
  } catch (error) {
34284
- console.error("Error generating site:", error);
34285
- process.exit(1);
34286
- }
34287
- });
34288
- program2.command("serve").description("Start a local development server").option("-o, --output <dir>", "Output directory", DEFAULT_OUTPUT_DIR).option("-p, --port <number>", "Port number", "3000").action(async (options2) => {
34289
- try {
34290
- const outputDir = path8.resolve(options2.output);
34291
- const port = parseInt(options2.port, 10);
34292
- await startServer(outputDir, port);
34293
- } catch (error) {
34294
- console.error("Error starting dev server:", error);
34295
- process.exit(1);
34276
+ deps.logger.error("Error creating new post:", error);
34277
+ deps.exit(1);
34278
+ return "";
34296
34279
  }
34297
- });
34298
- program2.command("css").description("Process CSS using PostCSS").option("-c, --config <file>", "Config file path", "bunki.config.ts").option("-o, --output <dir>", "Output directory", DEFAULT_OUTPUT_DIR).option("-w, --watch", "Watch for changes and rebuild").action(async (options2) => {
34280
+ }
34281
+ function registerNewCommand(program2) {
34282
+ return program2.command("new").description("Create a new blog post").argument("<title>", "Title of the post").option("-t, --tags <tags>", "Comma-separated list of tags", "").action(async (title, options2) => {
34283
+ await handleNewCommand(title, options2, defaultDeps4);
34284
+ });
34285
+ }
34286
+
34287
+ // src/cli/commands/serve.ts
34288
+ import path12 from "path";
34289
+
34290
+ // src/server.ts
34291
+ import fs3 from "fs";
34292
+ import path11 from "path";
34293
+ async function startServer(outputDir = DEFAULT_OUTPUT_DIR, port = 3000) {
34299
34294
  try {
34300
- const configPath = path8.resolve(options2.config);
34301
- const outputDir = path8.resolve(options2.output);
34302
- const config = await loadConfig(configPath);
34303
- const cssConfig = config.css || getDefaultCSSConfig();
34304
- if (!cssConfig.enabled) {
34305
- console.log("CSS processing is disabled in configuration");
34306
- return;
34307
- }
34308
- const processorOptions = {
34309
- css: cssConfig,
34310
- projectRoot: process.cwd(),
34311
- outputDir,
34312
- verbose: true
34313
- };
34314
- if (options2.watch) {
34315
- console.log("Starting CSS watch mode...");
34316
- cssConfig.watch = true;
34317
- await processCSS(processorOptions);
34318
- await watchCSS(processorOptions);
34319
- } else {
34320
- await processCSS(processorOptions);
34295
+ const stats = await fs3.promises.stat(outputDir);
34296
+ if (!stats.isDirectory()) {
34297
+ const msg = `Error: Output directory ${outputDir} does not exist or is not accessible.`;
34298
+ console.error(msg);
34299
+ console.log('Try running "bunki generate" first to build your site.');
34300
+ throw new Error(msg);
34321
34301
  }
34322
34302
  } catch (error) {
34323
- console.error("Error processing CSS:", error);
34324
- process.exit(1);
34303
+ const msg = `Error: Output directory ${outputDir} does not exist or is not accessible.`;
34304
+ console.error(msg);
34305
+ console.log('Try running "bunki generate" first to build your site.');
34306
+ throw new Error(msg);
34325
34307
  }
34326
- });
34327
- program2.command("images:push").description("Upload images to S3-compatible storage").option("-d, --domain <domain>", "Domain name for bucket identification (defaults to domain in bunki.config.ts)").option("-i, --images <dir>", "Images directory path", DEFAULT_IMAGES_DIR).option("--output-json <file>", "Output URL mapping to JSON file").action(async (options2) => {
34308
+ console.log(`Starting server for site in ${outputDir}...`);
34309
+ const server = Bun.serve({
34310
+ port,
34311
+ async fetch(req) {
34312
+ try {
34313
+ const url = new URL(req.url);
34314
+ let pathname = url.pathname;
34315
+ if (pathname === "/") {
34316
+ pathname = "/index.html";
34317
+ }
34318
+ if (pathname.endsWith("/")) {
34319
+ pathname = pathname + "index.html";
34320
+ }
34321
+ const homePaginationMatch = pathname.match(/^\/page\/(\d+)\/?$/);
34322
+ const tagPaginationMatch = pathname.match(/^\/tags\/([^\/]+)\/page\/(\d+)\/?$/);
34323
+ const yearPaginationMatch = pathname.match(/^\/(\d{4})\/page\/(\d+)\/?$/);
34324
+ let filePath = "";
34325
+ if (homePaginationMatch) {
34326
+ const pageNumber = homePaginationMatch[1];
34327
+ filePath = path11.join(outputDir, "page", pageNumber, "index.html");
34328
+ } else if (tagPaginationMatch) {
34329
+ const tagSlug = tagPaginationMatch[1];
34330
+ const pageNumber = tagPaginationMatch[2];
34331
+ filePath = path11.join(outputDir, "tags", tagSlug, "page", pageNumber, "index.html");
34332
+ } else if (yearPaginationMatch) {
34333
+ const year = yearPaginationMatch[1];
34334
+ const pageNumber = yearPaginationMatch[2];
34335
+ filePath = path11.join(outputDir, year, "page", pageNumber, "index.html");
34336
+ } else {
34337
+ const directPath = path11.join(outputDir, pathname);
34338
+ const withoutSlash = path11.join(outputDir, pathname + ".html");
34339
+ const withHtml = pathname.endsWith(".html") ? directPath : withoutSlash;
34340
+ const bunFileDirect = Bun.file(directPath);
34341
+ const bunFileHtml = Bun.file(withHtml);
34342
+ if (await bunFileDirect.exists()) {
34343
+ filePath = directPath;
34344
+ } else if (await bunFileHtml.exists()) {
34345
+ filePath = withHtml;
34346
+ } else {
34347
+ const indexPath = path11.join(outputDir, pathname, "index.html");
34348
+ const bunFileIndex = Bun.file(indexPath);
34349
+ if (await bunFileIndex.exists()) {
34350
+ filePath = indexPath;
34351
+ } else {
34352
+ console.log(`404 Not Found: ${pathname}`);
34353
+ return new Response(`<h1>404 Not Found</h1><p>Could not find ${pathname}</p>`, {
34354
+ status: 404,
34355
+ headers: { "Content-Type": "text/html" }
34356
+ });
34357
+ }
34358
+ }
34359
+ }
34360
+ console.log(`Serving file: ${filePath}`);
34361
+ const extname = path11.extname(filePath);
34362
+ let contentType = "text/html";
34363
+ switch (extname) {
34364
+ case ".js":
34365
+ contentType = "text/javascript";
34366
+ break;
34367
+ case ".css":
34368
+ contentType = "text/css";
34369
+ break;
34370
+ case ".json":
34371
+ contentType = "application/json";
34372
+ break;
34373
+ case ".png":
34374
+ contentType = "image/png";
34375
+ break;
34376
+ case ".jpg":
34377
+ case ".jpeg":
34378
+ contentType = "image/jpeg";
34379
+ break;
34380
+ case ".svg":
34381
+ contentType = "image/svg+xml";
34382
+ break;
34383
+ case ".xml":
34384
+ contentType = "application/xml";
34385
+ break;
34386
+ }
34387
+ try {
34388
+ const bunFile = Bun.file(filePath);
34389
+ return new Response(bunFile, {
34390
+ headers: { "Content-Type": contentType }
34391
+ });
34392
+ } catch (err) {
34393
+ console.error(`Error reading file ${filePath}:`, err);
34394
+ return new Response(`<h1>500 Server Error</h1><p>Error reading file: ${filePath}</p><pre>${err}</pre>`, {
34395
+ status: 500,
34396
+ headers: { "Content-Type": "text/html" }
34397
+ });
34398
+ }
34399
+ } catch (error) {
34400
+ console.error("Server error:", error);
34401
+ return new Response(`<h1>500 Server Error</h1><pre>${error}</pre>`, {
34402
+ status: 500,
34403
+ headers: { "Content-Type": "text/html" }
34404
+ });
34405
+ }
34406
+ }
34407
+ });
34408
+ console.log(`Bunki development server running at http://localhost:${port}/`);
34409
+ return server;
34410
+ }
34411
+
34412
+ // src/cli/commands/serve.ts
34413
+ var defaultDeps5 = {
34414
+ startServer,
34415
+ logger: console,
34416
+ exit: (code) => process.exit(code)
34417
+ };
34418
+ async function handleServeCommand(options2, deps = defaultDeps5) {
34328
34419
  try {
34329
- await uploadImages({
34330
- domain: options2.domain,
34331
- images: options2.images,
34332
- outputJson: options2.outputJson
34333
- });
34420
+ const outputDir = path12.resolve(options2.output);
34421
+ const port = parseInt(options2.port, 10);
34422
+ await deps.startServer(outputDir, port);
34334
34423
  } catch (error) {
34335
- console.error("Error uploading images:", error);
34336
- process.exit(1);
34424
+ deps.logger.error("Error starting dev server:", error);
34425
+ deps.exit(1);
34337
34426
  }
34338
- });
34339
- if (import.meta.url === Bun.main || process.argv[1] === import.meta.url.substring(7)) {
34340
- program2.parse(process.argv);
34427
+ }
34428
+ function registerServeCommand(program2) {
34429
+ return program2.command("serve").description("Start a local development server").option("-o, --output <dir>", "Output directory", DEFAULT_OUTPUT_DIR).option("-p, --port <number>", "Port number", "3000").action(async (options2) => {
34430
+ await handleServeCommand(options2);
34431
+ });
34432
+ }
34433
+
34434
+ // src/cli.ts
34435
+ var program2 = new Command;
34436
+ registerInitCommand(program2);
34437
+ registerNewCommand(program2);
34438
+ registerGenerateCommand(program2);
34439
+ registerServeCommand(program2);
34440
+ registerCssCommand(program2);
34441
+ registerImagesPushCommand(program2);
34442
+ program2.name("bunki").description("An opinionated static site generator built with Bun").version("0.5.3");
34443
+ if (import.meta.url === Bun.main) {
34444
+ program2.parse(Bun.argv);
34341
34445
  }