@lolyjs/core 0.3.0-alpha.4 → 0.3.0-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -9993,8 +9993,8 @@ __export(src_exports, {
9993
9993
  module.exports = __toCommonJS(src_exports);
9994
9994
 
9995
9995
  // src/server.ts
9996
- var import_fs23 = __toESM(require("fs"));
9997
- var import_path29 = __toESM(require("path"));
9996
+ var import_fs25 = __toESM(require("fs"));
9997
+ var import_path32 = __toESM(require("path"));
9998
9998
 
9999
9999
  // modules/server/utils/server-dir.ts
10000
10000
  var import_fs2 = __toESM(require("fs"));
@@ -11830,6 +11830,7 @@ async function processRewrites(urlPath, compiledRewrites, req) {
11830
11830
  const normalizedPath = urlPath.replace(/\/$/, "") || "/";
11831
11831
  if (normalizedPath.startsWith("/static/") || // Static assets (client.js, client.css, etc.)
11832
11832
  normalizedPath.startsWith("/__fw/") || // Framework internal routes (hot reload, etc.)
11833
+ normalizedPath.startsWith("/_loly/") || // Framework internal routes (image optimization, etc.)
11833
11834
  normalizedPath === "/favicon.ico" || // Favicon
11834
11835
  normalizedPath.startsWith("/wss/")) {
11835
11836
  if (process.env.NODE_ENV === "development") {
@@ -12739,7 +12740,7 @@ var ReaddirpStream = class extends import_node_stream.Readable {
12739
12740
  this._directoryFilter = normalizeFilter(opts.directoryFilter);
12740
12741
  const statMethod = opts.lstat ? import_promises.lstat : import_promises.stat;
12741
12742
  if (wantBigintFsStats) {
12742
- this._stat = (path33) => statMethod(path33, { bigint: true });
12743
+ this._stat = (path36) => statMethod(path36, { bigint: true });
12743
12744
  } else {
12744
12745
  this._stat = statMethod;
12745
12746
  }
@@ -12764,8 +12765,8 @@ var ReaddirpStream = class extends import_node_stream.Readable {
12764
12765
  const par = this.parent;
12765
12766
  const fil = par && par.files;
12766
12767
  if (fil && fil.length > 0) {
12767
- const { path: path33, depth } = par;
12768
- const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path33));
12768
+ const { path: path36, depth } = par;
12769
+ const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path36));
12769
12770
  const awaited = await Promise.all(slice);
12770
12771
  for (const entry of awaited) {
12771
12772
  if (!entry)
@@ -12805,20 +12806,20 @@ var ReaddirpStream = class extends import_node_stream.Readable {
12805
12806
  this.reading = false;
12806
12807
  }
12807
12808
  }
12808
- async _exploreDir(path33, depth) {
12809
+ async _exploreDir(path36, depth) {
12809
12810
  let files;
12810
12811
  try {
12811
- files = await (0, import_promises.readdir)(path33, this._rdOptions);
12812
+ files = await (0, import_promises.readdir)(path36, this._rdOptions);
12812
12813
  } catch (error) {
12813
12814
  this._onError(error);
12814
12815
  }
12815
- return { files, depth, path: path33 };
12816
+ return { files, depth, path: path36 };
12816
12817
  }
12817
- async _formatEntry(dirent, path33) {
12818
+ async _formatEntry(dirent, path36) {
12818
12819
  let entry;
12819
12820
  const basename3 = this._isDirent ? dirent.name : dirent;
12820
12821
  try {
12821
- const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path33, basename3));
12822
+ const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path36, basename3));
12822
12823
  entry = { path: (0, import_node_path.relative)(this._root, fullPath), fullPath, basename: basename3 };
12823
12824
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
12824
12825
  } catch (err) {
@@ -13218,16 +13219,16 @@ var delFromSet = (main, prop, item) => {
13218
13219
  };
13219
13220
  var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
13220
13221
  var FsWatchInstances = /* @__PURE__ */ new Map();
13221
- function createFsWatchInstance(path33, options, listener, errHandler, emitRaw) {
13222
+ function createFsWatchInstance(path36, options, listener, errHandler, emitRaw) {
13222
13223
  const handleEvent = (rawEvent, evPath) => {
13223
- listener(path33);
13224
- emitRaw(rawEvent, evPath, { watchedPath: path33 });
13225
- if (evPath && path33 !== evPath) {
13226
- fsWatchBroadcast(sysPath.resolve(path33, evPath), KEY_LISTENERS, sysPath.join(path33, evPath));
13224
+ listener(path36);
13225
+ emitRaw(rawEvent, evPath, { watchedPath: path36 });
13226
+ if (evPath && path36 !== evPath) {
13227
+ fsWatchBroadcast(sysPath.resolve(path36, evPath), KEY_LISTENERS, sysPath.join(path36, evPath));
13227
13228
  }
13228
13229
  };
13229
13230
  try {
13230
- return (0, import_fs17.watch)(path33, {
13231
+ return (0, import_fs17.watch)(path36, {
13231
13232
  persistent: options.persistent
13232
13233
  }, handleEvent);
13233
13234
  } catch (error) {
@@ -13243,12 +13244,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
13243
13244
  listener(val1, val2, val3);
13244
13245
  });
13245
13246
  };
13246
- var setFsWatchListener = (path33, fullPath, options, handlers) => {
13247
+ var setFsWatchListener = (path36, fullPath, options, handlers) => {
13247
13248
  const { listener, errHandler, rawEmitter } = handlers;
13248
13249
  let cont = FsWatchInstances.get(fullPath);
13249
13250
  let watcher;
13250
13251
  if (!options.persistent) {
13251
- watcher = createFsWatchInstance(path33, options, listener, errHandler, rawEmitter);
13252
+ watcher = createFsWatchInstance(path36, options, listener, errHandler, rawEmitter);
13252
13253
  if (!watcher)
13253
13254
  return;
13254
13255
  return watcher.close.bind(watcher);
@@ -13259,7 +13260,7 @@ var setFsWatchListener = (path33, fullPath, options, handlers) => {
13259
13260
  addAndConvert(cont, KEY_RAW, rawEmitter);
13260
13261
  } else {
13261
13262
  watcher = createFsWatchInstance(
13262
- path33,
13263
+ path36,
13263
13264
  options,
13264
13265
  fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
13265
13266
  errHandler,
@@ -13274,7 +13275,7 @@ var setFsWatchListener = (path33, fullPath, options, handlers) => {
13274
13275
  cont.watcherUnusable = true;
13275
13276
  if (isWindows && error.code === "EPERM") {
13276
13277
  try {
13277
- const fd = await (0, import_promises2.open)(path33, "r");
13278
+ const fd = await (0, import_promises2.open)(path36, "r");
13278
13279
  await fd.close();
13279
13280
  broadcastErr(error);
13280
13281
  } catch (err) {
@@ -13305,7 +13306,7 @@ var setFsWatchListener = (path33, fullPath, options, handlers) => {
13305
13306
  };
13306
13307
  };
13307
13308
  var FsWatchFileInstances = /* @__PURE__ */ new Map();
13308
- var setFsWatchFileListener = (path33, fullPath, options, handlers) => {
13309
+ var setFsWatchFileListener = (path36, fullPath, options, handlers) => {
13309
13310
  const { listener, rawEmitter } = handlers;
13310
13311
  let cont = FsWatchFileInstances.get(fullPath);
13311
13312
  const copts = cont && cont.options;
@@ -13327,7 +13328,7 @@ var setFsWatchFileListener = (path33, fullPath, options, handlers) => {
13327
13328
  });
13328
13329
  const currmtime = curr.mtimeMs;
13329
13330
  if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
13330
- foreach(cont.listeners, (listener2) => listener2(path33, curr));
13331
+ foreach(cont.listeners, (listener2) => listener2(path36, curr));
13331
13332
  }
13332
13333
  })
13333
13334
  };
@@ -13355,13 +13356,13 @@ var NodeFsHandler = class {
13355
13356
  * @param listener on fs change
13356
13357
  * @returns closer for the watcher instance
13357
13358
  */
13358
- _watchWithNodeFs(path33, listener) {
13359
+ _watchWithNodeFs(path36, listener) {
13359
13360
  const opts = this.fsw.options;
13360
- const directory = sysPath.dirname(path33);
13361
- const basename3 = sysPath.basename(path33);
13361
+ const directory = sysPath.dirname(path36);
13362
+ const basename3 = sysPath.basename(path36);
13362
13363
  const parent = this.fsw._getWatchedDir(directory);
13363
13364
  parent.add(basename3);
13364
- const absolutePath = sysPath.resolve(path33);
13365
+ const absolutePath = sysPath.resolve(path36);
13365
13366
  const options = {
13366
13367
  persistent: opts.persistent
13367
13368
  };
@@ -13371,12 +13372,12 @@ var NodeFsHandler = class {
13371
13372
  if (opts.usePolling) {
13372
13373
  const enableBin = opts.interval !== opts.binaryInterval;
13373
13374
  options.interval = enableBin && isBinaryPath(basename3) ? opts.binaryInterval : opts.interval;
13374
- closer = setFsWatchFileListener(path33, absolutePath, options, {
13375
+ closer = setFsWatchFileListener(path36, absolutePath, options, {
13375
13376
  listener,
13376
13377
  rawEmitter: this.fsw._emitRaw
13377
13378
  });
13378
13379
  } else {
13379
- closer = setFsWatchListener(path33, absolutePath, options, {
13380
+ closer = setFsWatchListener(path36, absolutePath, options, {
13380
13381
  listener,
13381
13382
  errHandler: this._boundHandleError,
13382
13383
  rawEmitter: this.fsw._emitRaw
@@ -13398,7 +13399,7 @@ var NodeFsHandler = class {
13398
13399
  let prevStats = stats;
13399
13400
  if (parent.has(basename3))
13400
13401
  return;
13401
- const listener = async (path33, newStats) => {
13402
+ const listener = async (path36, newStats) => {
13402
13403
  if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
13403
13404
  return;
13404
13405
  if (!newStats || newStats.mtimeMs === 0) {
@@ -13412,11 +13413,11 @@ var NodeFsHandler = class {
13412
13413
  this.fsw._emit(EV.CHANGE, file, newStats2);
13413
13414
  }
13414
13415
  if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
13415
- this.fsw._closeFile(path33);
13416
+ this.fsw._closeFile(path36);
13416
13417
  prevStats = newStats2;
13417
13418
  const closer2 = this._watchWithNodeFs(file, listener);
13418
13419
  if (closer2)
13419
- this.fsw._addPathCloser(path33, closer2);
13420
+ this.fsw._addPathCloser(path36, closer2);
13420
13421
  } else {
13421
13422
  prevStats = newStats2;
13422
13423
  }
@@ -13448,7 +13449,7 @@ var NodeFsHandler = class {
13448
13449
  * @param item basename of this item
13449
13450
  * @returns true if no more processing is needed for this entry.
13450
13451
  */
13451
- async _handleSymlink(entry, directory, path33, item) {
13452
+ async _handleSymlink(entry, directory, path36, item) {
13452
13453
  if (this.fsw.closed) {
13453
13454
  return;
13454
13455
  }
@@ -13458,7 +13459,7 @@ var NodeFsHandler = class {
13458
13459
  this.fsw._incrReadyCount();
13459
13460
  let linkPath;
13460
13461
  try {
13461
- linkPath = await (0, import_promises2.realpath)(path33);
13462
+ linkPath = await (0, import_promises2.realpath)(path36);
13462
13463
  } catch (e) {
13463
13464
  this.fsw._emitReady();
13464
13465
  return true;
@@ -13468,12 +13469,12 @@ var NodeFsHandler = class {
13468
13469
  if (dir.has(item)) {
13469
13470
  if (this.fsw._symlinkPaths.get(full) !== linkPath) {
13470
13471
  this.fsw._symlinkPaths.set(full, linkPath);
13471
- this.fsw._emit(EV.CHANGE, path33, entry.stats);
13472
+ this.fsw._emit(EV.CHANGE, path36, entry.stats);
13472
13473
  }
13473
13474
  } else {
13474
13475
  dir.add(item);
13475
13476
  this.fsw._symlinkPaths.set(full, linkPath);
13476
- this.fsw._emit(EV.ADD, path33, entry.stats);
13477
+ this.fsw._emit(EV.ADD, path36, entry.stats);
13477
13478
  }
13478
13479
  this.fsw._emitReady();
13479
13480
  return true;
@@ -13502,9 +13503,9 @@ var NodeFsHandler = class {
13502
13503
  return;
13503
13504
  }
13504
13505
  const item = entry.path;
13505
- let path33 = sysPath.join(directory, item);
13506
+ let path36 = sysPath.join(directory, item);
13506
13507
  current.add(item);
13507
- if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path33, item)) {
13508
+ if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path36, item)) {
13508
13509
  return;
13509
13510
  }
13510
13511
  if (this.fsw.closed) {
@@ -13513,8 +13514,8 @@ var NodeFsHandler = class {
13513
13514
  }
13514
13515
  if (item === target || !target && !previous.has(item)) {
13515
13516
  this.fsw._incrReadyCount();
13516
- path33 = sysPath.join(dir, sysPath.relative(dir, path33));
13517
- this._addToNodeFs(path33, initialAdd, wh, depth + 1);
13517
+ path36 = sysPath.join(dir, sysPath.relative(dir, path36));
13518
+ this._addToNodeFs(path36, initialAdd, wh, depth + 1);
13518
13519
  }
13519
13520
  }).on(EV.ERROR, this._boundHandleError);
13520
13521
  return new Promise((resolve3, reject) => {
@@ -13583,13 +13584,13 @@ var NodeFsHandler = class {
13583
13584
  * @param depth Child path actually targeted for watch
13584
13585
  * @param target Child path actually targeted for watch
13585
13586
  */
13586
- async _addToNodeFs(path33, initialAdd, priorWh, depth, target) {
13587
+ async _addToNodeFs(path36, initialAdd, priorWh, depth, target) {
13587
13588
  const ready = this.fsw._emitReady;
13588
- if (this.fsw._isIgnored(path33) || this.fsw.closed) {
13589
+ if (this.fsw._isIgnored(path36) || this.fsw.closed) {
13589
13590
  ready();
13590
13591
  return false;
13591
13592
  }
13592
- const wh = this.fsw._getWatchHelpers(path33);
13593
+ const wh = this.fsw._getWatchHelpers(path36);
13593
13594
  if (priorWh) {
13594
13595
  wh.filterPath = (entry) => priorWh.filterPath(entry);
13595
13596
  wh.filterDir = (entry) => priorWh.filterDir(entry);
@@ -13605,8 +13606,8 @@ var NodeFsHandler = class {
13605
13606
  const follow = this.fsw.options.followSymlinks;
13606
13607
  let closer;
13607
13608
  if (stats.isDirectory()) {
13608
- const absPath = sysPath.resolve(path33);
13609
- const targetPath = follow ? await (0, import_promises2.realpath)(path33) : path33;
13609
+ const absPath = sysPath.resolve(path36);
13610
+ const targetPath = follow ? await (0, import_promises2.realpath)(path36) : path36;
13610
13611
  if (this.fsw.closed)
13611
13612
  return;
13612
13613
  closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
@@ -13616,29 +13617,29 @@ var NodeFsHandler = class {
13616
13617
  this.fsw._symlinkPaths.set(absPath, targetPath);
13617
13618
  }
13618
13619
  } else if (stats.isSymbolicLink()) {
13619
- const targetPath = follow ? await (0, import_promises2.realpath)(path33) : path33;
13620
+ const targetPath = follow ? await (0, import_promises2.realpath)(path36) : path36;
13620
13621
  if (this.fsw.closed)
13621
13622
  return;
13622
13623
  const parent = sysPath.dirname(wh.watchPath);
13623
13624
  this.fsw._getWatchedDir(parent).add(wh.watchPath);
13624
13625
  this.fsw._emit(EV.ADD, wh.watchPath, stats);
13625
- closer = await this._handleDir(parent, stats, initialAdd, depth, path33, wh, targetPath);
13626
+ closer = await this._handleDir(parent, stats, initialAdd, depth, path36, wh, targetPath);
13626
13627
  if (this.fsw.closed)
13627
13628
  return;
13628
13629
  if (targetPath !== void 0) {
13629
- this.fsw._symlinkPaths.set(sysPath.resolve(path33), targetPath);
13630
+ this.fsw._symlinkPaths.set(sysPath.resolve(path36), targetPath);
13630
13631
  }
13631
13632
  } else {
13632
13633
  closer = this._handleFile(wh.watchPath, stats, initialAdd);
13633
13634
  }
13634
13635
  ready();
13635
13636
  if (closer)
13636
- this.fsw._addPathCloser(path33, closer);
13637
+ this.fsw._addPathCloser(path36, closer);
13637
13638
  return false;
13638
13639
  } catch (error) {
13639
13640
  if (this.fsw._handleError(error)) {
13640
13641
  ready();
13641
- return path33;
13642
+ return path36;
13642
13643
  }
13643
13644
  }
13644
13645
  }
@@ -13681,26 +13682,26 @@ function createPattern(matcher) {
13681
13682
  }
13682
13683
  return () => false;
13683
13684
  }
13684
- function normalizePath(path33) {
13685
- if (typeof path33 !== "string")
13685
+ function normalizePath(path36) {
13686
+ if (typeof path36 !== "string")
13686
13687
  throw new Error("string expected");
13687
- path33 = sysPath2.normalize(path33);
13688
- path33 = path33.replace(/\\/g, "/");
13688
+ path36 = sysPath2.normalize(path36);
13689
+ path36 = path36.replace(/\\/g, "/");
13689
13690
  let prepend = false;
13690
- if (path33.startsWith("//"))
13691
+ if (path36.startsWith("//"))
13691
13692
  prepend = true;
13692
13693
  const DOUBLE_SLASH_RE2 = /\/\//;
13693
- while (path33.match(DOUBLE_SLASH_RE2))
13694
- path33 = path33.replace(DOUBLE_SLASH_RE2, "/");
13694
+ while (path36.match(DOUBLE_SLASH_RE2))
13695
+ path36 = path36.replace(DOUBLE_SLASH_RE2, "/");
13695
13696
  if (prepend)
13696
- path33 = "/" + path33;
13697
- return path33;
13697
+ path36 = "/" + path36;
13698
+ return path36;
13698
13699
  }
13699
13700
  function matchPatterns(patterns, testString, stats) {
13700
- const path33 = normalizePath(testString);
13701
+ const path36 = normalizePath(testString);
13701
13702
  for (let index = 0; index < patterns.length; index++) {
13702
13703
  const pattern = patterns[index];
13703
- if (pattern(path33, stats)) {
13704
+ if (pattern(path36, stats)) {
13704
13705
  return true;
13705
13706
  }
13706
13707
  }
@@ -13740,19 +13741,19 @@ var toUnix = (string) => {
13740
13741
  }
13741
13742
  return str;
13742
13743
  };
13743
- var normalizePathToUnix = (path33) => toUnix(sysPath2.normalize(toUnix(path33)));
13744
- var normalizeIgnored = (cwd = "") => (path33) => {
13745
- if (typeof path33 === "string") {
13746
- return normalizePathToUnix(sysPath2.isAbsolute(path33) ? path33 : sysPath2.join(cwd, path33));
13744
+ var normalizePathToUnix = (path36) => toUnix(sysPath2.normalize(toUnix(path36)));
13745
+ var normalizeIgnored = (cwd = "") => (path36) => {
13746
+ if (typeof path36 === "string") {
13747
+ return normalizePathToUnix(sysPath2.isAbsolute(path36) ? path36 : sysPath2.join(cwd, path36));
13747
13748
  } else {
13748
- return path33;
13749
+ return path36;
13749
13750
  }
13750
13751
  };
13751
- var getAbsolutePath = (path33, cwd) => {
13752
- if (sysPath2.isAbsolute(path33)) {
13753
- return path33;
13752
+ var getAbsolutePath = (path36, cwd) => {
13753
+ if (sysPath2.isAbsolute(path36)) {
13754
+ return path36;
13754
13755
  }
13755
- return sysPath2.join(cwd, path33);
13756
+ return sysPath2.join(cwd, path36);
13756
13757
  };
13757
13758
  var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
13758
13759
  var DirEntry = class {
@@ -13807,10 +13808,10 @@ var DirEntry = class {
13807
13808
  var STAT_METHOD_F = "stat";
13808
13809
  var STAT_METHOD_L = "lstat";
13809
13810
  var WatchHelper = class {
13810
- constructor(path33, follow, fsw) {
13811
+ constructor(path36, follow, fsw) {
13811
13812
  this.fsw = fsw;
13812
- const watchPath = path33;
13813
- this.path = path33 = path33.replace(REPLACER_RE, "");
13813
+ const watchPath = path36;
13814
+ this.path = path36 = path36.replace(REPLACER_RE, "");
13814
13815
  this.watchPath = watchPath;
13815
13816
  this.fullWatchPath = sysPath2.resolve(watchPath);
13816
13817
  this.dirParts = [];
@@ -13932,20 +13933,20 @@ var FSWatcher = class extends import_events.EventEmitter {
13932
13933
  this._closePromise = void 0;
13933
13934
  let paths = unifyPaths(paths_);
13934
13935
  if (cwd) {
13935
- paths = paths.map((path33) => {
13936
- const absPath = getAbsolutePath(path33, cwd);
13936
+ paths = paths.map((path36) => {
13937
+ const absPath = getAbsolutePath(path36, cwd);
13937
13938
  return absPath;
13938
13939
  });
13939
13940
  }
13940
- paths.forEach((path33) => {
13941
- this._removeIgnoredPath(path33);
13941
+ paths.forEach((path36) => {
13942
+ this._removeIgnoredPath(path36);
13942
13943
  });
13943
13944
  this._userIgnored = void 0;
13944
13945
  if (!this._readyCount)
13945
13946
  this._readyCount = 0;
13946
13947
  this._readyCount += paths.length;
13947
- Promise.all(paths.map(async (path33) => {
13948
- const res = await this._nodeFsHandler._addToNodeFs(path33, !_internal, void 0, 0, _origAdd);
13948
+ Promise.all(paths.map(async (path36) => {
13949
+ const res = await this._nodeFsHandler._addToNodeFs(path36, !_internal, void 0, 0, _origAdd);
13949
13950
  if (res)
13950
13951
  this._emitReady();
13951
13952
  return res;
@@ -13967,17 +13968,17 @@ var FSWatcher = class extends import_events.EventEmitter {
13967
13968
  return this;
13968
13969
  const paths = unifyPaths(paths_);
13969
13970
  const { cwd } = this.options;
13970
- paths.forEach((path33) => {
13971
- if (!sysPath2.isAbsolute(path33) && !this._closers.has(path33)) {
13971
+ paths.forEach((path36) => {
13972
+ if (!sysPath2.isAbsolute(path36) && !this._closers.has(path36)) {
13972
13973
  if (cwd)
13973
- path33 = sysPath2.join(cwd, path33);
13974
- path33 = sysPath2.resolve(path33);
13974
+ path36 = sysPath2.join(cwd, path36);
13975
+ path36 = sysPath2.resolve(path36);
13975
13976
  }
13976
- this._closePath(path33);
13977
- this._addIgnoredPath(path33);
13978
- if (this._watched.has(path33)) {
13977
+ this._closePath(path36);
13978
+ this._addIgnoredPath(path36);
13979
+ if (this._watched.has(path36)) {
13979
13980
  this._addIgnoredPath({
13980
- path: path33,
13981
+ path: path36,
13981
13982
  recursive: true
13982
13983
  });
13983
13984
  }
@@ -14041,38 +14042,38 @@ var FSWatcher = class extends import_events.EventEmitter {
14041
14042
  * @param stats arguments to be passed with event
14042
14043
  * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
14043
14044
  */
14044
- async _emit(event, path33, stats) {
14045
+ async _emit(event, path36, stats) {
14045
14046
  if (this.closed)
14046
14047
  return;
14047
14048
  const opts = this.options;
14048
14049
  if (isWindows)
14049
- path33 = sysPath2.normalize(path33);
14050
+ path36 = sysPath2.normalize(path36);
14050
14051
  if (opts.cwd)
14051
- path33 = sysPath2.relative(opts.cwd, path33);
14052
- const args = [path33];
14052
+ path36 = sysPath2.relative(opts.cwd, path36);
14053
+ const args = [path36];
14053
14054
  if (stats != null)
14054
14055
  args.push(stats);
14055
14056
  const awf = opts.awaitWriteFinish;
14056
14057
  let pw;
14057
- if (awf && (pw = this._pendingWrites.get(path33))) {
14058
+ if (awf && (pw = this._pendingWrites.get(path36))) {
14058
14059
  pw.lastChange = /* @__PURE__ */ new Date();
14059
14060
  return this;
14060
14061
  }
14061
14062
  if (opts.atomic) {
14062
14063
  if (event === EVENTS.UNLINK) {
14063
- this._pendingUnlinks.set(path33, [event, ...args]);
14064
+ this._pendingUnlinks.set(path36, [event, ...args]);
14064
14065
  setTimeout(() => {
14065
- this._pendingUnlinks.forEach((entry, path34) => {
14066
+ this._pendingUnlinks.forEach((entry, path37) => {
14066
14067
  this.emit(...entry);
14067
14068
  this.emit(EVENTS.ALL, ...entry);
14068
- this._pendingUnlinks.delete(path34);
14069
+ this._pendingUnlinks.delete(path37);
14069
14070
  });
14070
14071
  }, typeof opts.atomic === "number" ? opts.atomic : 100);
14071
14072
  return this;
14072
14073
  }
14073
- if (event === EVENTS.ADD && this._pendingUnlinks.has(path33)) {
14074
+ if (event === EVENTS.ADD && this._pendingUnlinks.has(path36)) {
14074
14075
  event = EVENTS.CHANGE;
14075
- this._pendingUnlinks.delete(path33);
14076
+ this._pendingUnlinks.delete(path36);
14076
14077
  }
14077
14078
  }
14078
14079
  if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
@@ -14090,16 +14091,16 @@ var FSWatcher = class extends import_events.EventEmitter {
14090
14091
  this.emitWithAll(event, args);
14091
14092
  }
14092
14093
  };
14093
- this._awaitWriteFinish(path33, awf.stabilityThreshold, event, awfEmit);
14094
+ this._awaitWriteFinish(path36, awf.stabilityThreshold, event, awfEmit);
14094
14095
  return this;
14095
14096
  }
14096
14097
  if (event === EVENTS.CHANGE) {
14097
- const isThrottled = !this._throttle(EVENTS.CHANGE, path33, 50);
14098
+ const isThrottled = !this._throttle(EVENTS.CHANGE, path36, 50);
14098
14099
  if (isThrottled)
14099
14100
  return this;
14100
14101
  }
14101
14102
  if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
14102
- const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path33) : path33;
14103
+ const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path36) : path36;
14103
14104
  let stats2;
14104
14105
  try {
14105
14106
  stats2 = await (0, import_promises3.stat)(fullPath);
@@ -14130,23 +14131,23 @@ var FSWatcher = class extends import_events.EventEmitter {
14130
14131
  * @param timeout duration of time to suppress duplicate actions
14131
14132
  * @returns tracking object or false if action should be suppressed
14132
14133
  */
14133
- _throttle(actionType, path33, timeout) {
14134
+ _throttle(actionType, path36, timeout) {
14134
14135
  if (!this._throttled.has(actionType)) {
14135
14136
  this._throttled.set(actionType, /* @__PURE__ */ new Map());
14136
14137
  }
14137
14138
  const action = this._throttled.get(actionType);
14138
14139
  if (!action)
14139
14140
  throw new Error("invalid throttle");
14140
- const actionPath = action.get(path33);
14141
+ const actionPath = action.get(path36);
14141
14142
  if (actionPath) {
14142
14143
  actionPath.count++;
14143
14144
  return false;
14144
14145
  }
14145
14146
  let timeoutObject;
14146
14147
  const clear = () => {
14147
- const item = action.get(path33);
14148
+ const item = action.get(path36);
14148
14149
  const count = item ? item.count : 0;
14149
- action.delete(path33);
14150
+ action.delete(path36);
14150
14151
  clearTimeout(timeoutObject);
14151
14152
  if (item)
14152
14153
  clearTimeout(item.timeoutObject);
@@ -14154,7 +14155,7 @@ var FSWatcher = class extends import_events.EventEmitter {
14154
14155
  };
14155
14156
  timeoutObject = setTimeout(clear, timeout);
14156
14157
  const thr = { timeoutObject, clear, count: 0 };
14157
- action.set(path33, thr);
14158
+ action.set(path36, thr);
14158
14159
  return thr;
14159
14160
  }
14160
14161
  _incrReadyCount() {
@@ -14168,44 +14169,44 @@ var FSWatcher = class extends import_events.EventEmitter {
14168
14169
  * @param event
14169
14170
  * @param awfEmit Callback to be called when ready for event to be emitted.
14170
14171
  */
14171
- _awaitWriteFinish(path33, threshold, event, awfEmit) {
14172
+ _awaitWriteFinish(path36, threshold, event, awfEmit) {
14172
14173
  const awf = this.options.awaitWriteFinish;
14173
14174
  if (typeof awf !== "object")
14174
14175
  return;
14175
14176
  const pollInterval = awf.pollInterval;
14176
14177
  let timeoutHandler;
14177
- let fullPath = path33;
14178
- if (this.options.cwd && !sysPath2.isAbsolute(path33)) {
14179
- fullPath = sysPath2.join(this.options.cwd, path33);
14178
+ let fullPath = path36;
14179
+ if (this.options.cwd && !sysPath2.isAbsolute(path36)) {
14180
+ fullPath = sysPath2.join(this.options.cwd, path36);
14180
14181
  }
14181
14182
  const now = /* @__PURE__ */ new Date();
14182
14183
  const writes = this._pendingWrites;
14183
14184
  function awaitWriteFinishFn(prevStat) {
14184
14185
  (0, import_fs18.stat)(fullPath, (err, curStat) => {
14185
- if (err || !writes.has(path33)) {
14186
+ if (err || !writes.has(path36)) {
14186
14187
  if (err && err.code !== "ENOENT")
14187
14188
  awfEmit(err);
14188
14189
  return;
14189
14190
  }
14190
14191
  const now2 = Number(/* @__PURE__ */ new Date());
14191
14192
  if (prevStat && curStat.size !== prevStat.size) {
14192
- writes.get(path33).lastChange = now2;
14193
+ writes.get(path36).lastChange = now2;
14193
14194
  }
14194
- const pw = writes.get(path33);
14195
+ const pw = writes.get(path36);
14195
14196
  const df = now2 - pw.lastChange;
14196
14197
  if (df >= threshold) {
14197
- writes.delete(path33);
14198
+ writes.delete(path36);
14198
14199
  awfEmit(void 0, curStat);
14199
14200
  } else {
14200
14201
  timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
14201
14202
  }
14202
14203
  });
14203
14204
  }
14204
- if (!writes.has(path33)) {
14205
- writes.set(path33, {
14205
+ if (!writes.has(path36)) {
14206
+ writes.set(path36, {
14206
14207
  lastChange: now,
14207
14208
  cancelWait: () => {
14208
- writes.delete(path33);
14209
+ writes.delete(path36);
14209
14210
  clearTimeout(timeoutHandler);
14210
14211
  return event;
14211
14212
  }
@@ -14216,8 +14217,8 @@ var FSWatcher = class extends import_events.EventEmitter {
14216
14217
  /**
14217
14218
  * Determines whether user has asked to ignore this path.
14218
14219
  */
14219
- _isIgnored(path33, stats) {
14220
- if (this.options.atomic && DOT_RE.test(path33))
14220
+ _isIgnored(path36, stats) {
14221
+ if (this.options.atomic && DOT_RE.test(path36))
14221
14222
  return true;
14222
14223
  if (!this._userIgnored) {
14223
14224
  const { cwd } = this.options;
@@ -14227,17 +14228,17 @@ var FSWatcher = class extends import_events.EventEmitter {
14227
14228
  const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
14228
14229
  this._userIgnored = anymatch(list, void 0);
14229
14230
  }
14230
- return this._userIgnored(path33, stats);
14231
+ return this._userIgnored(path36, stats);
14231
14232
  }
14232
- _isntIgnored(path33, stat4) {
14233
- return !this._isIgnored(path33, stat4);
14233
+ _isntIgnored(path36, stat4) {
14234
+ return !this._isIgnored(path36, stat4);
14234
14235
  }
14235
14236
  /**
14236
14237
  * Provides a set of common helpers and properties relating to symlink handling.
14237
14238
  * @param path file or directory pattern being watched
14238
14239
  */
14239
- _getWatchHelpers(path33) {
14240
- return new WatchHelper(path33, this.options.followSymlinks, this);
14240
+ _getWatchHelpers(path36) {
14241
+ return new WatchHelper(path36, this.options.followSymlinks, this);
14241
14242
  }
14242
14243
  // Directory helpers
14243
14244
  // -----------------
@@ -14269,63 +14270,63 @@ var FSWatcher = class extends import_events.EventEmitter {
14269
14270
  * @param item base path of item/directory
14270
14271
  */
14271
14272
  _remove(directory, item, isDirectory) {
14272
- const path33 = sysPath2.join(directory, item);
14273
- const fullPath = sysPath2.resolve(path33);
14274
- isDirectory = isDirectory != null ? isDirectory : this._watched.has(path33) || this._watched.has(fullPath);
14275
- if (!this._throttle("remove", path33, 100))
14273
+ const path36 = sysPath2.join(directory, item);
14274
+ const fullPath = sysPath2.resolve(path36);
14275
+ isDirectory = isDirectory != null ? isDirectory : this._watched.has(path36) || this._watched.has(fullPath);
14276
+ if (!this._throttle("remove", path36, 100))
14276
14277
  return;
14277
14278
  if (!isDirectory && this._watched.size === 1) {
14278
14279
  this.add(directory, item, true);
14279
14280
  }
14280
- const wp = this._getWatchedDir(path33);
14281
+ const wp = this._getWatchedDir(path36);
14281
14282
  const nestedDirectoryChildren = wp.getChildren();
14282
- nestedDirectoryChildren.forEach((nested) => this._remove(path33, nested));
14283
+ nestedDirectoryChildren.forEach((nested) => this._remove(path36, nested));
14283
14284
  const parent = this._getWatchedDir(directory);
14284
14285
  const wasTracked = parent.has(item);
14285
14286
  parent.remove(item);
14286
14287
  if (this._symlinkPaths.has(fullPath)) {
14287
14288
  this._symlinkPaths.delete(fullPath);
14288
14289
  }
14289
- let relPath = path33;
14290
+ let relPath = path36;
14290
14291
  if (this.options.cwd)
14291
- relPath = sysPath2.relative(this.options.cwd, path33);
14292
+ relPath = sysPath2.relative(this.options.cwd, path36);
14292
14293
  if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
14293
14294
  const event = this._pendingWrites.get(relPath).cancelWait();
14294
14295
  if (event === EVENTS.ADD)
14295
14296
  return;
14296
14297
  }
14297
- this._watched.delete(path33);
14298
+ this._watched.delete(path36);
14298
14299
  this._watched.delete(fullPath);
14299
14300
  const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
14300
- if (wasTracked && !this._isIgnored(path33))
14301
- this._emit(eventName, path33);
14302
- this._closePath(path33);
14301
+ if (wasTracked && !this._isIgnored(path36))
14302
+ this._emit(eventName, path36);
14303
+ this._closePath(path36);
14303
14304
  }
14304
14305
  /**
14305
14306
  * Closes all watchers for a path
14306
14307
  */
14307
- _closePath(path33) {
14308
- this._closeFile(path33);
14309
- const dir = sysPath2.dirname(path33);
14310
- this._getWatchedDir(dir).remove(sysPath2.basename(path33));
14308
+ _closePath(path36) {
14309
+ this._closeFile(path36);
14310
+ const dir = sysPath2.dirname(path36);
14311
+ this._getWatchedDir(dir).remove(sysPath2.basename(path36));
14311
14312
  }
14312
14313
  /**
14313
14314
  * Closes only file-specific watchers
14314
14315
  */
14315
- _closeFile(path33) {
14316
- const closers = this._closers.get(path33);
14316
+ _closeFile(path36) {
14317
+ const closers = this._closers.get(path36);
14317
14318
  if (!closers)
14318
14319
  return;
14319
14320
  closers.forEach((closer) => closer());
14320
- this._closers.delete(path33);
14321
+ this._closers.delete(path36);
14321
14322
  }
14322
- _addPathCloser(path33, closer) {
14323
+ _addPathCloser(path36, closer) {
14323
14324
  if (!closer)
14324
14325
  return;
14325
- let list = this._closers.get(path33);
14326
+ let list = this._closers.get(path36);
14326
14327
  if (!list) {
14327
14328
  list = [];
14328
- this._closers.set(path33, list);
14329
+ this._closers.set(path36, list);
14329
14330
  }
14330
14331
  list.push(closer);
14331
14332
  }
@@ -14541,7 +14542,20 @@ var DEFAULT_CONFIG = {
14541
14542
  ssr: true,
14542
14543
  ssg: true
14543
14544
  },
14544
- plugins: []
14545
+ plugins: [],
14546
+ images: {
14547
+ remotePatterns: [],
14548
+ domains: [],
14549
+ deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
14550
+ imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
14551
+ formats: ["image/webp", "image/avif"],
14552
+ quality: 75,
14553
+ minimumCacheTTL: 60,
14554
+ dangerouslyAllowSVG: false,
14555
+ contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
14556
+ maxWidth: 3840,
14557
+ maxHeight: 3840
14558
+ }
14545
14559
  };
14546
14560
  function deepMerge(target, source) {
14547
14561
  const result = { ...target };
@@ -14658,6 +14672,53 @@ function validateConfig(config, projectRoot) {
14658
14672
  if (typeof config.rendering.ssg !== "boolean") {
14659
14673
  errors.push("config.rendering.ssg must be a boolean");
14660
14674
  }
14675
+ if (config.images) {
14676
+ if (config.images.quality !== void 0) {
14677
+ if (typeof config.images.quality !== "number" || config.images.quality < 1 || config.images.quality > 100) {
14678
+ errors.push("config.images.quality must be a number between 1 and 100");
14679
+ }
14680
+ }
14681
+ if (config.images.minimumCacheTTL !== void 0) {
14682
+ if (typeof config.images.minimumCacheTTL !== "number" || config.images.minimumCacheTTL < 0) {
14683
+ errors.push("config.images.minimumCacheTTL must be a non-negative number");
14684
+ }
14685
+ }
14686
+ if (config.images.deviceSizes) {
14687
+ if (!Array.isArray(config.images.deviceSizes) || config.images.deviceSizes.some((s) => typeof s !== "number" || s <= 0)) {
14688
+ errors.push("config.images.deviceSizes must be an array of positive numbers");
14689
+ }
14690
+ }
14691
+ if (config.images.imageSizes) {
14692
+ if (!Array.isArray(config.images.imageSizes) || config.images.imageSizes.some((s) => typeof s !== "number" || s <= 0)) {
14693
+ errors.push("config.images.imageSizes must be an array of positive numbers");
14694
+ }
14695
+ }
14696
+ if (config.images.formats) {
14697
+ const validFormats = ["image/webp", "image/avif"];
14698
+ if (!Array.isArray(config.images.formats) || config.images.formats.some((f) => !validFormats.includes(f))) {
14699
+ errors.push(`config.images.formats must be an array containing only: ${validFormats.join(", ")}`);
14700
+ }
14701
+ }
14702
+ if (config.images.remotePatterns) {
14703
+ if (!Array.isArray(config.images.remotePatterns)) {
14704
+ errors.push("config.images.remotePatterns must be an array");
14705
+ } else {
14706
+ config.images.remotePatterns.forEach((pattern, idx) => {
14707
+ if (!pattern.hostname || typeof pattern.hostname !== "string") {
14708
+ errors.push(`config.images.remotePatterns[${idx}].hostname must be a non-empty string`);
14709
+ }
14710
+ if (pattern.protocol && !["http", "https"].includes(pattern.protocol)) {
14711
+ errors.push(`config.images.remotePatterns[${idx}].protocol must be 'http' or 'https'`);
14712
+ }
14713
+ });
14714
+ }
14715
+ }
14716
+ if (config.images.domains) {
14717
+ if (!Array.isArray(config.images.domains) || config.images.domains.some((d) => typeof d !== "string")) {
14718
+ errors.push("config.images.domains must be an array of strings");
14719
+ }
14720
+ }
14721
+ }
14661
14722
  if (errors.length > 0) {
14662
14723
  const errorMessage = [
14663
14724
  "\u274C Configuration validation failed:",
@@ -15003,12 +15064,12 @@ var DEFAULT_IGNORED_PATHS = [
15003
15064
  /^\/sockjs-node/
15004
15065
  // Hot reload websocket
15005
15066
  ];
15006
- function shouldIgnorePath(path33, ignoredPaths) {
15067
+ function shouldIgnorePath(path36, ignoredPaths) {
15007
15068
  return ignoredPaths.some((pattern) => {
15008
15069
  if (typeof pattern === "string") {
15009
- return path33 === pattern || path33.startsWith(pattern);
15070
+ return path36 === pattern || path36.startsWith(pattern);
15010
15071
  }
15011
- return pattern.test(path33);
15072
+ return pattern.test(path36);
15012
15073
  });
15013
15074
  }
15014
15075
  function requestLoggerMiddleware(options = {}) {
@@ -15167,11 +15228,11 @@ function createStrictRateLimiterFromConfig(config) {
15167
15228
  }
15168
15229
 
15169
15230
  // modules/server/middleware/auto-rate-limit.ts
15170
- function matchesStrictPattern(path33, patterns) {
15231
+ function matchesStrictPattern(path36, patterns) {
15171
15232
  for (const pattern of patterns) {
15172
15233
  const regexPattern = pattern.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*").replace(/\//g, "\\/");
15173
15234
  const regex = new RegExp(`^${regexPattern}$`);
15174
- if (regex.test(path33)) {
15235
+ if (regex.test(path36)) {
15175
15236
  return true;
15176
15237
  }
15177
15238
  }
@@ -15694,7 +15755,7 @@ function createDocumentTree(options) {
15694
15755
  }),
15695
15756
  ...extraMetaTags,
15696
15757
  ...linkTags,
15697
- ...entrypointFiles.length > 0 ? entrypointFiles.slice(0, -1).map(
15758
+ ...entrypointFiles.length > 0 ? entrypointFiles.map(
15698
15759
  (file) => import_react.default.createElement("link", {
15699
15760
  key: `preload-${file}`,
15700
15761
  rel: "preload",
@@ -15715,6 +15776,13 @@ function createDocumentTree(options) {
15715
15776
  href: faviconPath,
15716
15777
  type: faviconType || (faviconPath.endsWith(".ico") ? "image/x-icon" : "image/png")
15717
15778
  }),
15779
+ // Preload CSS para evitar bloqueo de renderizado
15780
+ import_react.default.createElement("link", {
15781
+ key: "preload-css",
15782
+ rel: "preload",
15783
+ href: clientCssPath,
15784
+ as: "style"
15785
+ }),
15718
15786
  import_react.default.createElement("link", {
15719
15787
  rel: "stylesheet",
15720
15788
  href: clientCssPath
@@ -16861,6 +16929,438 @@ async function renderErrorPageWithStream(errorPage, req, res, error, routeChunks
16861
16929
  }
16862
16930
  }
16863
16931
 
16932
+ // modules/server/image-optimizer/index.ts
16933
+ var import_sharp = __toESM(require("sharp"));
16934
+ var import_fs24 = __toESM(require("fs"));
16935
+ var import_path30 = __toESM(require("path"));
16936
+
16937
+ // modules/server/image-optimizer/validation.ts
16938
+ var import_path28 = __toESM(require("path"));
16939
+ function isRemoteUrl(url) {
16940
+ return url.startsWith("http://") || url.startsWith("https://");
16941
+ }
16942
+ function sanitizeImagePath(imagePath) {
16943
+ const normalized = import_path28.default.normalize(imagePath).replace(/^(\.\.(\/|\\|$))+/, "");
16944
+ return normalized.replace(/^[/\\]+/, "");
16945
+ }
16946
+ function patternToRegex(pattern) {
16947
+ const parts = [];
16948
+ if (pattern.protocol) {
16949
+ parts.push(pattern.protocol === "https" ? "https" : "http");
16950
+ } else {
16951
+ parts.push("https?");
16952
+ }
16953
+ parts.push("://");
16954
+ let hostnamePattern = pattern.hostname.replace(/\./g, "\\.").replace(/\*\*/g, ".*").replace(/\*/g, "[^.]*");
16955
+ parts.push(hostnamePattern);
16956
+ if (pattern.port) {
16957
+ parts.push(`:${pattern.port}`);
16958
+ }
16959
+ if (pattern.pathname) {
16960
+ let pathnamePattern = pattern.pathname.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*");
16961
+ parts.push(pathnamePattern);
16962
+ } else {
16963
+ parts.push(".*");
16964
+ }
16965
+ const regexSource = `^${parts.join("")}`;
16966
+ return new RegExp(regexSource);
16967
+ }
16968
+ function validateRemoteUrl(url, config) {
16969
+ if (!config.remotePatterns && !config.domains) {
16970
+ return false;
16971
+ }
16972
+ try {
16973
+ const urlObj = new URL(url);
16974
+ const protocol = urlObj.protocol.replace(":", "");
16975
+ const hostname = urlObj.hostname;
16976
+ const port = urlObj.port || "";
16977
+ const pathname = urlObj.pathname;
16978
+ if (config.remotePatterns && config.remotePatterns.length > 0) {
16979
+ for (const pattern of config.remotePatterns) {
16980
+ const regex = patternToRegex(pattern);
16981
+ const testUrl = `${protocol}://${hostname}${port ? `:${port}` : ""}${pathname}`;
16982
+ if (regex.test(testUrl)) {
16983
+ if (pattern.protocol && pattern.protocol !== protocol) {
16984
+ continue;
16985
+ }
16986
+ if (pattern.port && pattern.port !== port) {
16987
+ continue;
16988
+ }
16989
+ return true;
16990
+ }
16991
+ }
16992
+ }
16993
+ if (config.domains && config.domains.length > 0) {
16994
+ for (const domain of config.domains) {
16995
+ const domainPattern = domain.replace(/\./g, "\\.").replace(/\*\*/g, ".*").replace(/\*/g, "[^.]*");
16996
+ const regex = new RegExp(`^${domainPattern}$`);
16997
+ if (regex.test(hostname)) {
16998
+ if (process.env.NODE_ENV === "production" && protocol !== "https") {
16999
+ continue;
17000
+ }
17001
+ return true;
17002
+ }
17003
+ }
17004
+ }
17005
+ return false;
17006
+ } catch (error) {
17007
+ return false;
17008
+ }
17009
+ }
17010
+ function validateImageDimensions(width, height, config) {
17011
+ const maxWidth = config.maxWidth || 3840;
17012
+ const maxHeight = config.maxHeight || 3840;
17013
+ if (width !== void 0 && (width <= 0 || width > maxWidth)) {
17014
+ return {
17015
+ valid: false,
17016
+ error: `Image width must be between 1 and ${maxWidth}, got ${width}`
17017
+ };
17018
+ }
17019
+ if (height !== void 0 && (height <= 0 || height > maxHeight)) {
17020
+ return {
17021
+ valid: false,
17022
+ error: `Image height must be between 1 and ${maxHeight}, got ${height}`
17023
+ };
17024
+ }
17025
+ return { valid: true };
17026
+ }
17027
+ function validateQuality(quality) {
17028
+ if (quality === void 0) {
17029
+ return { valid: true };
17030
+ }
17031
+ if (typeof quality !== "number" || quality < 1 || quality > 100) {
17032
+ return {
17033
+ valid: false,
17034
+ error: `Image quality must be between 1 and 100, got ${quality}`
17035
+ };
17036
+ }
17037
+ return { valid: true };
17038
+ }
17039
+
17040
+ // modules/server/image-optimizer/cache.ts
17041
+ var import_fs23 = __toESM(require("fs"));
17042
+ var import_path29 = __toESM(require("path"));
17043
+ var import_crypto = __toESM(require("crypto"));
17044
+ function generateCacheKey(src, width, height, quality, format) {
17045
+ const data = `${src}-${width || ""}-${height || ""}-${quality || ""}-${format || ""}`;
17046
+ return import_crypto.default.createHash("sha256").update(data).digest("hex");
17047
+ }
17048
+ function getCacheDir(projectRoot, config) {
17049
+ const buildDir = getBuildDir(projectRoot, config);
17050
+ return import_path29.default.join(buildDir, "cache", "images");
17051
+ }
17052
+ function ensureCacheDir(cacheDir) {
17053
+ if (!import_fs23.default.existsSync(cacheDir)) {
17054
+ import_fs23.default.mkdirSync(cacheDir, { recursive: true });
17055
+ }
17056
+ }
17057
+ function getCachedImagePath(cacheKey, extension, cacheDir) {
17058
+ return import_path29.default.join(cacheDir, `${cacheKey}.${extension}`);
17059
+ }
17060
+ function hasCachedImage(cacheKey, extension, cacheDir) {
17061
+ const cachedPath = getCachedImagePath(cacheKey, extension, cacheDir);
17062
+ return import_fs23.default.existsSync(cachedPath);
17063
+ }
17064
+ function readCachedImage(cacheKey, extension, cacheDir) {
17065
+ const cachedPath = getCachedImagePath(cacheKey, extension, cacheDir);
17066
+ try {
17067
+ if (import_fs23.default.existsSync(cachedPath)) {
17068
+ return import_fs23.default.readFileSync(cachedPath);
17069
+ }
17070
+ } catch (error) {
17071
+ console.warn(`[image-optimizer] Failed to read cached image: ${cachedPath}`, error);
17072
+ }
17073
+ return null;
17074
+ }
17075
+ function writeCachedImage(cacheKey, extension, cacheDir, imageBuffer) {
17076
+ ensureCacheDir(cacheDir);
17077
+ const cachedPath = getCachedImagePath(cacheKey, extension, cacheDir);
17078
+ try {
17079
+ import_fs23.default.writeFileSync(cachedPath, imageBuffer);
17080
+ } catch (error) {
17081
+ console.warn(`[image-optimizer] Failed to write cached image: ${cachedPath}`, error);
17082
+ }
17083
+ }
17084
+ function getImageMimeType(format) {
17085
+ const formatMap = {
17086
+ webp: "image/webp",
17087
+ avif: "image/avif",
17088
+ jpeg: "image/jpeg",
17089
+ jpg: "image/jpeg",
17090
+ png: "image/png",
17091
+ gif: "image/gif",
17092
+ svg: "image/svg+xml"
17093
+ };
17094
+ const normalized = format.toLowerCase();
17095
+ return formatMap[normalized] || "image/jpeg";
17096
+ }
17097
+ function getImageExtension(format) {
17098
+ const formatMap = {
17099
+ "image/webp": "webp",
17100
+ "image/avif": "avif",
17101
+ "image/jpeg": "jpg",
17102
+ "image/png": "png",
17103
+ "image/gif": "gif",
17104
+ "image/svg+xml": "svg",
17105
+ webp: "webp",
17106
+ avif: "avif",
17107
+ jpeg: "jpg",
17108
+ jpg: "jpg",
17109
+ png: "png",
17110
+ gif: "gif",
17111
+ svg: "svg"
17112
+ };
17113
+ const normalized = format.toLowerCase();
17114
+ return formatMap[normalized] || "jpg";
17115
+ }
17116
+
17117
+ // modules/server/image-optimizer/index.ts
17118
+ async function downloadRemoteImage(url, timeout = 1e4) {
17119
+ let fetchFn;
17120
+ try {
17121
+ if (typeof fetch !== "undefined") {
17122
+ fetchFn = fetch;
17123
+ } else {
17124
+ const { fetch: undiciFetch } = await import("undici");
17125
+ fetchFn = undiciFetch;
17126
+ }
17127
+ } catch (error) {
17128
+ throw new Error("Failed to load fetch implementation. Node 18+ required or install undici.");
17129
+ }
17130
+ const controller = new AbortController();
17131
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
17132
+ try {
17133
+ const response = await fetchFn(url, {
17134
+ signal: controller.signal,
17135
+ headers: {
17136
+ "User-Agent": "Loly-Image-Optimizer/1.0"
17137
+ }
17138
+ });
17139
+ clearTimeout(timeoutId);
17140
+ if (!response.ok) {
17141
+ throw new Error(`Failed to download image: ${response.status} ${response.statusText}`);
17142
+ }
17143
+ const arrayBuffer = await response.arrayBuffer();
17144
+ return Buffer.from(arrayBuffer);
17145
+ } catch (error) {
17146
+ clearTimeout(timeoutId);
17147
+ if (error instanceof Error && error.name === "AbortError") {
17148
+ throw new Error(`Image download timeout after ${timeout}ms`);
17149
+ }
17150
+ throw error;
17151
+ }
17152
+ }
17153
+ function readLocalImage(src, projectRoot, config) {
17154
+ const sanitized = sanitizeImagePath(src);
17155
+ const staticDir = getStaticDir(projectRoot, config);
17156
+ const staticPath = import_path30.default.join(staticDir, sanitized);
17157
+ if (import_fs24.default.existsSync(staticPath)) {
17158
+ return import_fs24.default.readFileSync(staticPath);
17159
+ }
17160
+ if (src.startsWith("/")) {
17161
+ const absolutePath = import_path30.default.join(projectRoot, sanitized);
17162
+ if (import_fs24.default.existsSync(absolutePath)) {
17163
+ return import_fs24.default.readFileSync(absolutePath);
17164
+ }
17165
+ }
17166
+ throw new Error(`Image not found: ${src}`);
17167
+ }
17168
+ function determineOutputFormat(sourceFormat, requestedFormat, config) {
17169
+ if (sourceFormat === "svg") {
17170
+ return "svg";
17171
+ }
17172
+ if (requestedFormat && requestedFormat !== "auto") {
17173
+ return requestedFormat;
17174
+ }
17175
+ const supportedFormats = config.formats || ["image/webp"];
17176
+ if (supportedFormats.includes("image/avif")) {
17177
+ return "avif";
17178
+ }
17179
+ if (supportedFormats.includes("image/webp")) {
17180
+ return "webp";
17181
+ }
17182
+ return sourceFormat === "svg" ? "jpeg" : sourceFormat;
17183
+ }
17184
+ async function optimizeImage(options, projectRoot, config) {
17185
+ const imageConfig = config.images || {};
17186
+ const dimValidation = validateImageDimensions(options.width, options.height, imageConfig);
17187
+ if (!dimValidation.valid) {
17188
+ throw new Error(dimValidation.error);
17189
+ }
17190
+ const qualityValidation = validateQuality(options.quality);
17191
+ if (!qualityValidation.valid) {
17192
+ throw new Error(qualityValidation.error);
17193
+ }
17194
+ if (isRemoteUrl(options.src)) {
17195
+ if (!validateRemoteUrl(options.src, imageConfig)) {
17196
+ throw new Error(`Remote image domain not allowed: ${options.src}`);
17197
+ }
17198
+ }
17199
+ const sourceFormat = import_path30.default.extname(options.src).slice(1).toLowerCase() || "jpeg";
17200
+ const outputFormat = determineOutputFormat(
17201
+ sourceFormat,
17202
+ options.format,
17203
+ imageConfig
17204
+ );
17205
+ const cacheKey = generateCacheKey(
17206
+ options.src,
17207
+ options.width,
17208
+ options.height,
17209
+ options.quality || imageConfig.quality || 75,
17210
+ outputFormat
17211
+ );
17212
+ const cacheDir = getCacheDir(projectRoot, config);
17213
+ const extension = getImageExtension(outputFormat);
17214
+ if (hasCachedImage(cacheKey, extension, cacheDir)) {
17215
+ const cached = readCachedImage(cacheKey, extension, cacheDir);
17216
+ if (cached) {
17217
+ const metadata2 = await (0, import_sharp.default)(cached).metadata();
17218
+ return {
17219
+ buffer: cached,
17220
+ format: outputFormat,
17221
+ mimeType: getImageMimeType(outputFormat),
17222
+ width: metadata2.width || options.width || 0,
17223
+ height: metadata2.height || options.height || 0
17224
+ };
17225
+ }
17226
+ }
17227
+ let imageBuffer;
17228
+ if (isRemoteUrl(options.src)) {
17229
+ imageBuffer = await downloadRemoteImage(options.src);
17230
+ } else {
17231
+ imageBuffer = readLocalImage(options.src, projectRoot, config);
17232
+ }
17233
+ if (outputFormat === "svg" || sourceFormat === "svg") {
17234
+ if (!imageConfig.dangerouslyAllowSVG) {
17235
+ throw new Error("SVG images are not allowed. Set images.dangerouslyAllowSVG to true to enable.");
17236
+ }
17237
+ return {
17238
+ buffer: imageBuffer,
17239
+ format: "svg",
17240
+ mimeType: "image/svg+xml",
17241
+ width: options.width || 0,
17242
+ height: options.height || 0
17243
+ };
17244
+ }
17245
+ let sharpInstance = (0, import_sharp.default)(imageBuffer);
17246
+ const metadata = await sharpInstance.metadata();
17247
+ if (options.width || options.height) {
17248
+ const fit = options.fit || "cover";
17249
+ sharpInstance = sharpInstance.resize(options.width, options.height, {
17250
+ fit,
17251
+ withoutEnlargement: true
17252
+ });
17253
+ }
17254
+ const quality = options.quality || imageConfig.quality || 75;
17255
+ switch (outputFormat) {
17256
+ case "webp":
17257
+ sharpInstance = sharpInstance.webp({ quality });
17258
+ break;
17259
+ case "avif":
17260
+ sharpInstance = sharpInstance.avif({ quality });
17261
+ break;
17262
+ case "jpeg":
17263
+ case "jpg":
17264
+ sharpInstance = sharpInstance.jpeg({ quality });
17265
+ break;
17266
+ case "png":
17267
+ sharpInstance = sharpInstance.png({ quality: Math.round(quality / 100 * 9) });
17268
+ break;
17269
+ default:
17270
+ sharpInstance = sharpInstance.jpeg({ quality });
17271
+ }
17272
+ const optimizedBuffer = await sharpInstance.toBuffer();
17273
+ const finalMetadata = await (0, import_sharp.default)(optimizedBuffer).metadata();
17274
+ writeCachedImage(cacheKey, extension, cacheDir, optimizedBuffer);
17275
+ return {
17276
+ buffer: optimizedBuffer,
17277
+ format: outputFormat,
17278
+ mimeType: getImageMimeType(outputFormat),
17279
+ width: finalMetadata.width || options.width || metadata.width || 0,
17280
+ height: finalMetadata.height || options.height || metadata.height || 0
17281
+ };
17282
+ }
17283
+
17284
+ // modules/server/handlers/image.ts
17285
+ async function handleImageRequest(options) {
17286
+ const { req, res, projectRoot, config } = options;
17287
+ try {
17288
+ const src = req.query.src;
17289
+ const width = req.query.w ? parseInt(req.query.w, 10) : void 0;
17290
+ const height = req.query.h ? parseInt(req.query.h, 10) : void 0;
17291
+ const quality = req.query.q ? parseInt(req.query.q, 10) : void 0;
17292
+ const format = req.query.format;
17293
+ const fit = req.query.fit;
17294
+ if (!src) {
17295
+ res.status(400).json({
17296
+ error: "Missing required parameter: src"
17297
+ });
17298
+ return;
17299
+ }
17300
+ if (typeof src !== "string") {
17301
+ res.status(400).json({
17302
+ error: "Parameter 'src' must be a string"
17303
+ });
17304
+ return;
17305
+ }
17306
+ const result = await optimizeImage(
17307
+ {
17308
+ src,
17309
+ width,
17310
+ height,
17311
+ quality,
17312
+ format,
17313
+ fit
17314
+ },
17315
+ projectRoot,
17316
+ config
17317
+ );
17318
+ const imageConfig = config.images || {};
17319
+ const cacheTTL = imageConfig.minimumCacheTTL || 60;
17320
+ res.setHeader("Content-Type", result.mimeType);
17321
+ res.setHeader("Content-Length", result.buffer.length);
17322
+ res.setHeader("Cache-Control", `public, max-age=${cacheTTL}, immutable`);
17323
+ res.setHeader("X-Content-Type-Options", "nosniff");
17324
+ res.send(result.buffer);
17325
+ } catch (error) {
17326
+ if (error instanceof Error) {
17327
+ if (error.message.includes("not allowed")) {
17328
+ res.status(403).json({
17329
+ error: "Forbidden",
17330
+ message: error.message
17331
+ });
17332
+ return;
17333
+ }
17334
+ if (error.message.includes("not found") || error.message.includes("Image not found")) {
17335
+ res.status(404).json({
17336
+ error: "Not Found",
17337
+ message: error.message
17338
+ });
17339
+ return;
17340
+ }
17341
+ if (error.message.includes("must be")) {
17342
+ res.status(400).json({
17343
+ error: "Bad Request",
17344
+ message: error.message
17345
+ });
17346
+ return;
17347
+ }
17348
+ if (error.message.includes("timeout") || error.message.includes("download")) {
17349
+ res.status(504).json({
17350
+ error: "Gateway Timeout",
17351
+ message: error.message
17352
+ });
17353
+ return;
17354
+ }
17355
+ }
17356
+ console.error("[image-optimizer] Error processing image:", error);
17357
+ res.status(500).json({
17358
+ error: "Internal Server Error",
17359
+ message: "Failed to process image"
17360
+ });
17361
+ }
17362
+ }
17363
+
16864
17364
  // modules/server/routes.ts
16865
17365
  init_globals();
16866
17366
 
@@ -17022,7 +17522,7 @@ function validateRealtimeConfig(config) {
17022
17522
  }
17023
17523
 
17024
17524
  // modules/server/routes.ts
17025
- var import_path28 = __toESM(require("path"));
17525
+ var import_path31 = __toESM(require("path"));
17026
17526
  var cachedRewriteLoader = null;
17027
17527
  var cachedProjectRoot = null;
17028
17528
  var cachedIsDev = null;
@@ -17050,10 +17550,20 @@ function setupRoutes(options) {
17050
17550
  } = options;
17051
17551
  const routeChunks = routeLoader.loadRouteChunks();
17052
17552
  const rewriteLoader = getRewriteLoader(projectRoot, isDev);
17053
- const ssgOutDir = import_path28.default.join(
17054
- config ? getBuildDir(projectRoot, config) : import_path28.default.join(projectRoot, BUILD_FOLDER_NAME),
17553
+ const ssgOutDir = import_path31.default.join(
17554
+ config ? getBuildDir(projectRoot, config) : import_path31.default.join(projectRoot, BUILD_FOLDER_NAME),
17055
17555
  "ssg"
17056
17556
  );
17557
+ if (config) {
17558
+ app.get("/_loly/image", async (req, res) => {
17559
+ await handleImageRequest({
17560
+ req,
17561
+ res,
17562
+ projectRoot,
17563
+ config
17564
+ });
17565
+ });
17566
+ }
17057
17567
  app.all("/api/*", async (req, res) => {
17058
17568
  const apiRoutes = isDev && getRoutes ? (await getRoutes()).apiRoutes : initialApiRoutes;
17059
17569
  const serverConfig = await getServerConfig(projectRoot);
@@ -18100,7 +18610,7 @@ var import_cors = __toESM(require("cors"));
18100
18610
  var import_helmet = __toESM(require("helmet"));
18101
18611
  var import_cookie_parser = __toESM(require("cookie-parser"));
18102
18612
  var import_compression = __toESM(require("compression"));
18103
- var import_crypto = __toESM(require("crypto"));
18613
+ var import_crypto2 = __toESM(require("crypto"));
18104
18614
  var setupApplication = async ({
18105
18615
  projectRoot
18106
18616
  }) => {
@@ -18209,7 +18719,7 @@ var setupApplication = async ({
18209
18719
  if (process.env.NODE_ENV !== "development" && security?.contentSecurityPolicy !== false) {
18210
18720
  app.use(
18211
18721
  (req, res, next) => {
18212
- const nonce = import_crypto.default.randomBytes(16).toString("base64");
18722
+ const nonce = import_crypto2.default.randomBytes(16).toString("base64");
18213
18723
  res.locals.nonce = nonce;
18214
18724
  next();
18215
18725
  }
@@ -18280,8 +18790,8 @@ var setupApplication = async ({
18280
18790
 
18281
18791
  // src/server.ts
18282
18792
  var import_dotenv2 = __toESM(require("dotenv"));
18283
- var envPath = import_path29.default.join(process.cwd(), ".env");
18284
- if (import_fs23.default.existsSync(envPath)) {
18793
+ var envPath = import_path32.default.join(process.cwd(), ".env");
18794
+ if (import_fs25.default.existsSync(envPath)) {
18285
18795
  import_dotenv2.default.config({ path: envPath });
18286
18796
  } else {
18287
18797
  import_dotenv2.default.config();
@@ -18302,8 +18812,8 @@ async function startServer(options = {}) {
18302
18812
  }
18303
18813
  const port = options.port ?? (process.env.PORT ? parseInt(process.env.PORT, 10) : void 0) ?? config.server.port;
18304
18814
  const host = process.env.HOST ?? (!isDev ? "0.0.0.0" : void 0) ?? config.server.host;
18305
- const appDir = options.appDir ?? (isDev ? getAppDir(projectRoot, config) : import_path29.default.join(getBuildDir(projectRoot, config), "server"));
18306
- if (!isDev && !import_fs23.default.existsSync(appDir)) {
18815
+ const appDir = options.appDir ?? (isDev ? getAppDir(projectRoot, config) : import_path32.default.join(getBuildDir(projectRoot, config), "server"));
18816
+ if (!isDev && !import_fs25.default.existsSync(appDir)) {
18307
18817
  logger4.error("Compiled directory not found", void 0, {
18308
18818
  buildDir: config.directories.build,
18309
18819
  appDir,
@@ -18374,14 +18884,14 @@ async function startProdServer(options = {}) {
18374
18884
  }
18375
18885
 
18376
18886
  // modules/build/index.ts
18377
- var import_path36 = __toESM(require("path"));
18378
- var import_fs26 = __toESM(require("fs"));
18887
+ var import_path39 = __toESM(require("path"));
18888
+ var import_fs28 = __toESM(require("fs"));
18379
18889
 
18380
18890
  // modules/build/ssg/builder.ts
18381
- var import_path33 = __toESM(require("path"));
18891
+ var import_path36 = __toESM(require("path"));
18382
18892
 
18383
18893
  // modules/build/ssg/path.ts
18384
- var import_path30 = __toESM(require("path"));
18894
+ var import_path33 = __toESM(require("path"));
18385
18895
  function buildPathFromPattern(pattern, params) {
18386
18896
  const segments = pattern.split("/").filter(Boolean);
18387
18897
  const parts = [];
@@ -18410,12 +18920,12 @@ function buildPathFromPattern(pattern, params) {
18410
18920
  }
18411
18921
  function pathToOutDir(baseDir, urlPath) {
18412
18922
  const clean = urlPath === "/" ? "" : urlPath.replace(/^\/+/, "");
18413
- return import_path30.default.join(baseDir, clean);
18923
+ return import_path33.default.join(baseDir, clean);
18414
18924
  }
18415
18925
 
18416
18926
  // modules/build/ssg/renderer.ts
18417
- var import_fs24 = __toESM(require("fs"));
18418
- var import_path31 = __toESM(require("path"));
18927
+ var import_fs26 = __toESM(require("fs"));
18928
+ var import_path34 = __toESM(require("path"));
18419
18929
  var import_server3 = require("react-dom/server");
18420
18930
  init_globals();
18421
18931
  async function renderStaticRoute(projectRoot, ssgOutDir, route, urlPath, params, config) {
@@ -18551,16 +19061,16 @@ async function renderStaticRoute(projectRoot, ssgOutDir, route, urlPath, params,
18551
19061
  const html = "<!DOCTYPE html>" + (0, import_server3.renderToString)(documentTree);
18552
19062
  const dir = pathToOutDir(ssgOutDir, urlPath);
18553
19063
  ensureDir(dir);
18554
- const htmlFile = import_path31.default.join(dir, "index.html");
18555
- const dataFile = import_path31.default.join(dir, "data.json");
18556
- import_fs24.default.writeFileSync(htmlFile, html, "utf-8");
18557
- import_fs24.default.writeFileSync(dataFile, JSON.stringify(initialData, null, 2), "utf-8");
19064
+ const htmlFile = import_path34.default.join(dir, "index.html");
19065
+ const dataFile = import_path34.default.join(dir, "data.json");
19066
+ import_fs26.default.writeFileSync(htmlFile, html, "utf-8");
19067
+ import_fs26.default.writeFileSync(dataFile, JSON.stringify(initialData, null, 2), "utf-8");
18558
19068
  }
18559
19069
 
18560
19070
  // modules/build/ssg/builder.ts
18561
19071
  init_globals();
18562
19072
  async function buildStaticPages(projectRoot, routes, config) {
18563
- const ssgOutDir = import_path33.default.join(projectRoot, BUILD_FOLDER_NAME, "ssg");
19073
+ const ssgOutDir = import_path36.default.join(projectRoot, BUILD_FOLDER_NAME, "ssg");
18564
19074
  ensureDir(ssgOutDir);
18565
19075
  for (const route of routes) {
18566
19076
  if (route.dynamic !== "force-static") continue;
@@ -18615,36 +19125,36 @@ async function buildStaticPages(projectRoot, routes, config) {
18615
19125
  }
18616
19126
 
18617
19127
  // modules/build/bundler/server.ts
18618
- var import_path35 = __toESM(require("path"));
18619
- var import_fs25 = __toESM(require("fs"));
19128
+ var import_path38 = __toESM(require("path"));
19129
+ var import_fs27 = __toESM(require("fs"));
18620
19130
  var import_esbuild = __toESM(require("esbuild"));
18621
19131
  init_globals();
18622
19132
  var SERVER_FILES = [INIT_FILE_NAME, CONFIG_FILE_NAME];
18623
19133
  function createPathAliasPlugin(projectRoot, outDir) {
18624
19134
  const aliases = loadAliasesFromTsconfig(projectRoot);
18625
- const tsconfigPath = import_path35.default.join(projectRoot, "tsconfig.json");
19135
+ const tsconfigPath = import_path38.default.join(projectRoot, "tsconfig.json");
18626
19136
  let baseUrl = ".";
18627
- if (import_fs25.default.existsSync(tsconfigPath)) {
19137
+ if (import_fs27.default.existsSync(tsconfigPath)) {
18628
19138
  try {
18629
- const tsconfig = JSON.parse(import_fs25.default.readFileSync(tsconfigPath, "utf-8"));
19139
+ const tsconfig = JSON.parse(import_fs27.default.readFileSync(tsconfigPath, "utf-8"));
18630
19140
  baseUrl = tsconfig.compilerOptions?.baseUrl ?? ".";
18631
19141
  } catch {
18632
19142
  }
18633
19143
  }
18634
19144
  function resolveAliasToRelative(importPath, sourceFile) {
18635
- if (importPath.startsWith(".") || importPath.startsWith("/") || import_path35.default.isAbsolute(importPath) || importPath.includes("node_modules")) {
19145
+ if (importPath.startsWith(".") || importPath.startsWith("/") || import_path38.default.isAbsolute(importPath) || importPath.includes("node_modules")) {
18636
19146
  return null;
18637
19147
  }
18638
19148
  for (const [aliasKey, aliasPath] of Object.entries(aliases)) {
18639
19149
  if (importPath.startsWith(aliasKey + "/") || importPath === aliasKey) {
18640
19150
  const restPath = importPath.startsWith(aliasKey + "/") ? importPath.slice(aliasKey.length + 1) : "";
18641
- const resolvedPath = restPath ? import_path35.default.join(aliasPath, restPath) : aliasPath;
19151
+ const resolvedPath = restPath ? import_path38.default.join(aliasPath, restPath) : aliasPath;
18642
19152
  let actualPath = null;
18643
19153
  const extensions = [".ts", ".tsx", ".js", ".jsx", ".json"];
18644
- if (import_fs25.default.existsSync(resolvedPath) && import_fs25.default.statSync(resolvedPath).isDirectory()) {
19154
+ if (import_fs27.default.existsSync(resolvedPath) && import_fs27.default.statSync(resolvedPath).isDirectory()) {
18645
19155
  for (const ext of extensions) {
18646
- const indexPath = import_path35.default.join(resolvedPath, `index${ext}`);
18647
- if (import_fs25.default.existsSync(indexPath)) {
19156
+ const indexPath = import_path38.default.join(resolvedPath, `index${ext}`);
19157
+ if (import_fs27.default.existsSync(indexPath)) {
18648
19158
  actualPath = indexPath;
18649
19159
  break;
18650
19160
  }
@@ -18652,20 +19162,20 @@ function createPathAliasPlugin(projectRoot, outDir) {
18652
19162
  } else {
18653
19163
  for (const ext of extensions) {
18654
19164
  const filePath = resolvedPath + ext;
18655
- if (import_fs25.default.existsSync(filePath)) {
19165
+ if (import_fs27.default.existsSync(filePath)) {
18656
19166
  actualPath = filePath;
18657
19167
  break;
18658
19168
  }
18659
19169
  }
18660
- if (!actualPath && import_fs25.default.existsSync(resolvedPath)) {
19170
+ if (!actualPath && import_fs27.default.existsSync(resolvedPath)) {
18661
19171
  actualPath = resolvedPath;
18662
19172
  }
18663
19173
  }
18664
19174
  if (actualPath) {
18665
- const relativePath = import_path35.default.relative(outDir, actualPath);
19175
+ const relativePath = import_path38.default.relative(outDir, actualPath);
18666
19176
  const normalizedPath = relativePath.replace(/\\/g, "/");
18667
19177
  const finalPath = normalizedPath.startsWith(".") ? normalizedPath : `./${normalizedPath}`;
18668
- const ext = import_path35.default.extname(finalPath);
19178
+ const ext = import_path38.default.extname(finalPath);
18669
19179
  const pathWithoutExt = ext === ".json" ? finalPath : finalPath.slice(0, -ext.length);
18670
19180
  return pathWithoutExt;
18671
19181
  }
@@ -18677,19 +19187,19 @@ function createPathAliasPlugin(projectRoot, outDir) {
18677
19187
  name: "path-alias-resolver",
18678
19188
  setup(build) {
18679
19189
  function resolveAliasToAbsolute(importPath) {
18680
- if (importPath.startsWith(".") || importPath.startsWith("/") || import_path35.default.isAbsolute(importPath) || importPath.includes("node_modules")) {
19190
+ if (importPath.startsWith(".") || importPath.startsWith("/") || import_path38.default.isAbsolute(importPath) || importPath.includes("node_modules")) {
18681
19191
  return null;
18682
19192
  }
18683
19193
  for (const [aliasKey, aliasPath] of Object.entries(aliases)) {
18684
19194
  if (importPath.startsWith(aliasKey + "/") || importPath === aliasKey) {
18685
19195
  const restPath = importPath.startsWith(aliasKey + "/") ? importPath.slice(aliasKey.length + 1) : "";
18686
- const resolvedPath = restPath ? import_path35.default.join(aliasPath, restPath) : aliasPath;
19196
+ const resolvedPath = restPath ? import_path38.default.join(aliasPath, restPath) : aliasPath;
18687
19197
  let actualPath = null;
18688
19198
  const extensions = [".ts", ".tsx", ".js", ".jsx", ".json"];
18689
- if (import_fs25.default.existsSync(resolvedPath) && import_fs25.default.statSync(resolvedPath).isDirectory()) {
19199
+ if (import_fs27.default.existsSync(resolvedPath) && import_fs27.default.statSync(resolvedPath).isDirectory()) {
18690
19200
  for (const ext of extensions) {
18691
- const indexPath = import_path35.default.join(resolvedPath, `index${ext}`);
18692
- if (import_fs25.default.existsSync(indexPath)) {
19201
+ const indexPath = import_path38.default.join(resolvedPath, `index${ext}`);
19202
+ if (import_fs27.default.existsSync(indexPath)) {
18693
19203
  actualPath = indexPath;
18694
19204
  break;
18695
19205
  }
@@ -18697,12 +19207,12 @@ function createPathAliasPlugin(projectRoot, outDir) {
18697
19207
  } else {
18698
19208
  for (const ext of extensions) {
18699
19209
  const filePath = resolvedPath + ext;
18700
- if (import_fs25.default.existsSync(filePath)) {
19210
+ if (import_fs27.default.existsSync(filePath)) {
18701
19211
  actualPath = filePath;
18702
19212
  break;
18703
19213
  }
18704
19214
  }
18705
- if (!actualPath && import_fs25.default.existsSync(resolvedPath)) {
19215
+ if (!actualPath && import_fs27.default.existsSync(resolvedPath)) {
18706
19216
  actualPath = resolvedPath;
18707
19217
  }
18708
19218
  }
@@ -18715,7 +19225,7 @@ function createPathAliasPlugin(projectRoot, outDir) {
18715
19225
  }
18716
19226
  build.onResolve({ filter: /^[^./]/ }, (args) => {
18717
19227
  const absolutePath = resolveAliasToAbsolute(args.path);
18718
- if (absolutePath && import_fs25.default.existsSync(absolutePath)) {
19228
+ if (absolutePath && import_fs27.default.existsSync(absolutePath)) {
18719
19229
  return {
18720
19230
  path: absolutePath,
18721
19231
  namespace: "file"
@@ -18724,13 +19234,13 @@ function createPathAliasPlugin(projectRoot, outDir) {
18724
19234
  return null;
18725
19235
  });
18726
19236
  build.onLoad({ filter: /\.(ts|tsx|js|jsx)$/ }, (args) => {
18727
- const fileName = import_path35.default.basename(args.path);
19237
+ const fileName = import_path38.default.basename(args.path);
18728
19238
  const isServerFile = SERVER_FILES.some((f) => fileName === `${f}.ts` || fileName === `${f}.tsx` || fileName === `${f}.js` || fileName === `${f}.jsx`);
18729
- const isInProjectRoot = import_path35.default.dirname(args.path) === projectRoot;
19239
+ const isInProjectRoot = import_path38.default.dirname(args.path) === projectRoot;
18730
19240
  if (!isServerFile || !isInProjectRoot) {
18731
19241
  return null;
18732
19242
  }
18733
- const contents = import_fs25.default.readFileSync(args.path, "utf-8");
19243
+ const contents = import_fs27.default.readFileSync(args.path, "utf-8");
18734
19244
  let transformed = contents;
18735
19245
  const aliasPatterns = Object.keys(aliases).sort((a, b) => b.length - a.length);
18736
19246
  for (const aliasKey of aliasPatterns) {
@@ -18750,7 +19260,7 @@ function createPathAliasPlugin(projectRoot, outDir) {
18750
19260
  }
18751
19261
  return {
18752
19262
  contents: transformed,
18753
- loader: import_path35.default.extname(args.path).slice(1)
19263
+ loader: import_path38.default.extname(args.path).slice(1)
18754
19264
  };
18755
19265
  });
18756
19266
  }
@@ -18762,13 +19272,13 @@ function rewritePathAliasesInOutput(outDir, projectRoot, appDir) {
18762
19272
  for (const [aliasKey, aliasSourcePath] of Object.entries(aliases)) {
18763
19273
  if (aliasPath.startsWith(aliasKey + "/") || aliasPath === aliasKey) {
18764
19274
  const restPath = aliasPath.startsWith(aliasKey + "/") ? aliasPath.slice(aliasKey.length + 1) : "";
18765
- const resolvedSourcePath = restPath ? import_path35.default.join(aliasSourcePath, restPath) : aliasSourcePath;
19275
+ const resolvedSourcePath = restPath ? import_path38.default.join(aliasSourcePath, restPath) : aliasSourcePath;
18766
19276
  let actualSourcePath = null;
18767
19277
  const extensions = [".ts", ".tsx", ".js", ".jsx", ".json"];
18768
- if (import_fs25.default.existsSync(resolvedSourcePath) && import_fs25.default.statSync(resolvedSourcePath).isDirectory()) {
19278
+ if (import_fs27.default.existsSync(resolvedSourcePath) && import_fs27.default.statSync(resolvedSourcePath).isDirectory()) {
18769
19279
  for (const ext of extensions) {
18770
- const indexPath = import_path35.default.join(resolvedSourcePath, `index${ext}`);
18771
- if (import_fs25.default.existsSync(indexPath)) {
19280
+ const indexPath = import_path38.default.join(resolvedSourcePath, `index${ext}`);
19281
+ if (import_fs27.default.existsSync(indexPath)) {
18772
19282
  actualSourcePath = indexPath;
18773
19283
  break;
18774
19284
  }
@@ -18776,21 +19286,21 @@ function rewritePathAliasesInOutput(outDir, projectRoot, appDir) {
18776
19286
  } else {
18777
19287
  for (const ext of extensions) {
18778
19288
  const filePath = resolvedSourcePath + ext;
18779
- if (import_fs25.default.existsSync(filePath)) {
19289
+ if (import_fs27.default.existsSync(filePath)) {
18780
19290
  actualSourcePath = filePath;
18781
19291
  break;
18782
19292
  }
18783
19293
  }
18784
- if (!actualSourcePath && import_fs25.default.existsSync(resolvedSourcePath)) {
19294
+ if (!actualSourcePath && import_fs27.default.existsSync(resolvedSourcePath)) {
18785
19295
  actualSourcePath = resolvedSourcePath;
18786
19296
  }
18787
19297
  }
18788
19298
  if (actualSourcePath) {
18789
- const relativeFromApp = import_path35.default.relative(appDir, actualSourcePath);
18790
- const outputPath = import_path35.default.join(outDir, relativeFromApp);
19299
+ const relativeFromApp = import_path38.default.relative(appDir, actualSourcePath);
19300
+ const outputPath = import_path38.default.join(outDir, relativeFromApp);
18791
19301
  const pathWithoutExt = outputPath.replace(/\.(ts|tsx|js|jsx|json)$/, "");
18792
19302
  const compiledPath = pathWithoutExt + ".mjs";
18793
- if (import_fs25.default.existsSync(compiledPath)) {
19303
+ if (import_fs27.default.existsSync(compiledPath)) {
18794
19304
  return compiledPath;
18795
19305
  }
18796
19306
  }
@@ -18799,17 +19309,17 @@ function rewritePathAliasesInOutput(outDir, projectRoot, appDir) {
18799
19309
  return null;
18800
19310
  }
18801
19311
  function walkAndRewrite(dir) {
18802
- if (!import_fs25.default.existsSync(dir)) return;
18803
- const items = import_fs25.default.readdirSync(dir, { withFileTypes: true });
19312
+ if (!import_fs27.default.existsSync(dir)) return;
19313
+ const items = import_fs27.default.readdirSync(dir, { withFileTypes: true });
18804
19314
  for (const item of items) {
18805
- const full = import_path35.default.join(dir, item.name);
19315
+ const full = import_path38.default.join(dir, item.name);
18806
19316
  if (item.isDirectory()) {
18807
19317
  walkAndRewrite(full);
18808
19318
  continue;
18809
19319
  }
18810
19320
  if (item.isFile() && full.endsWith(".mjs")) {
18811
19321
  try {
18812
- let content = import_fs25.default.readFileSync(full, "utf-8");
19322
+ let content = import_fs27.default.readFileSync(full, "utf-8");
18813
19323
  let modified = false;
18814
19324
  const aliasPatterns = Object.keys(aliases).sort((a, b) => b.length - a.length);
18815
19325
  for (const aliasKey of aliasPatterns) {
@@ -18821,8 +19331,8 @@ function rewritePathAliasesInOutput(outDir, projectRoot, appDir) {
18821
19331
  content = content.replace(aliasInQuotesPattern, (match, quote1, rest, quote2) => {
18822
19332
  const fullAliasPath = aliasKey + (rest || "");
18823
19333
  const resolvedOutputPath = resolveAliasToOutputPath(fullAliasPath);
18824
- if (resolvedOutputPath && import_fs25.default.existsSync(resolvedOutputPath)) {
18825
- const relativePath = import_path35.default.relative(import_path35.default.dirname(full), resolvedOutputPath);
19334
+ if (resolvedOutputPath && import_fs27.default.existsSync(resolvedOutputPath)) {
19335
+ const relativePath = import_path38.default.relative(import_path38.default.dirname(full), resolvedOutputPath);
18826
19336
  let normalizedPath = relativePath.replace(/\\/g, "/");
18827
19337
  if (!normalizedPath.startsWith(".")) {
18828
19338
  normalizedPath = `./${normalizedPath}`;
@@ -18835,7 +19345,7 @@ function rewritePathAliasesInOutput(outDir, projectRoot, appDir) {
18835
19345
  });
18836
19346
  }
18837
19347
  if (modified) {
18838
- import_fs25.default.writeFileSync(full, content, "utf-8");
19348
+ import_fs27.default.writeFileSync(full, content, "utf-8");
18839
19349
  }
18840
19350
  } catch (error) {
18841
19351
  console.warn(`[framework] Warning: Could not rewrite path aliases in ${full}:`, error instanceof Error ? error.message : String(error));
@@ -18846,14 +19356,14 @@ function rewritePathAliasesInOutput(outDir, projectRoot, appDir) {
18846
19356
  walkAndRewrite(outDir);
18847
19357
  }
18848
19358
  function copyStaticFilesFromApp(appDir, outDir) {
18849
- if (!import_fs25.default.existsSync(appDir)) return;
19359
+ if (!import_fs27.default.existsSync(appDir)) return;
18850
19360
  const sourceExtensions = [".ts", ".tsx", ".js", ".jsx", ".d.ts", ".map"];
18851
19361
  function walk(srcDir, destDir) {
18852
- if (!import_fs25.default.existsSync(srcDir)) return;
18853
- const items = import_fs25.default.readdirSync(srcDir, { withFileTypes: true });
19362
+ if (!import_fs27.default.existsSync(srcDir)) return;
19363
+ const items = import_fs27.default.readdirSync(srcDir, { withFileTypes: true });
18854
19364
  for (const item of items) {
18855
- const srcPath = import_path35.default.join(srcDir, item.name);
18856
- const destPath = import_path35.default.join(destDir, item.name);
19365
+ const srcPath = import_path38.default.join(srcDir, item.name);
19366
+ const destPath = import_path38.default.join(destDir, item.name);
18857
19367
  if (item.isDirectory()) {
18858
19368
  if (item.name === "node_modules" || item.name.startsWith(".")) {
18859
19369
  continue;
@@ -18863,10 +19373,10 @@ function copyStaticFilesFromApp(appDir, outDir) {
18863
19373
  continue;
18864
19374
  }
18865
19375
  if (item.isFile()) {
18866
- const ext = import_path35.default.extname(item.name).toLowerCase();
19376
+ const ext = import_path38.default.extname(item.name).toLowerCase();
18867
19377
  if (!sourceExtensions.includes(ext)) {
18868
19378
  ensureDir(destDir);
18869
- import_fs25.default.copyFileSync(srcPath, destPath);
19379
+ import_fs27.default.copyFileSync(srcPath, destPath);
18870
19380
  }
18871
19381
  }
18872
19382
  }
@@ -18876,9 +19386,9 @@ function copyStaticFilesFromApp(appDir, outDir) {
18876
19386
  function collectAppSources(appDir) {
18877
19387
  const entries = [];
18878
19388
  function walk(dir) {
18879
- const items = import_fs25.default.readdirSync(dir, { withFileTypes: true });
19389
+ const items = import_fs27.default.readdirSync(dir, { withFileTypes: true });
18880
19390
  for (const item of items) {
18881
- const full = import_path35.default.join(dir, item.name);
19391
+ const full = import_path38.default.join(dir, item.name);
18882
19392
  if (item.isDirectory()) {
18883
19393
  walk(full);
18884
19394
  continue;
@@ -18895,7 +19405,7 @@ function collectAppSources(appDir) {
18895
19405
  return entries;
18896
19406
  }
18897
19407
  async function buildServerApp(projectRoot, appDir, config) {
18898
- const outDir = import_path35.default.join(projectRoot, BUILD_FOLDER_NAME, "server");
19408
+ const outDir = import_path38.default.join(projectRoot, BUILD_FOLDER_NAME, "server");
18899
19409
  const entryPoints = collectAppSources(appDir);
18900
19410
  ensureDir(outDir);
18901
19411
  if (entryPoints.length === 0) {
@@ -18914,7 +19424,7 @@ async function buildServerApp(projectRoot, appDir, config) {
18914
19424
  bundle: true,
18915
19425
  splitting: false,
18916
19426
  logLevel: "info",
18917
- tsconfig: import_path35.default.join(projectRoot, "tsconfig.json"),
19427
+ tsconfig: import_path38.default.join(projectRoot, "tsconfig.json"),
18918
19428
  packages: "external",
18919
19429
  outExtension: { ".js": ".mjs" },
18920
19430
  plugins: [pathAliasPlugin]
@@ -18923,9 +19433,9 @@ async function buildServerApp(projectRoot, appDir, config) {
18923
19433
  copyStaticFilesFromApp(appDir, outDir);
18924
19434
  rewritePathAliasesInOutput(outDir, projectRoot, appDir);
18925
19435
  for (const fileName of SERVER_FILES) {
18926
- const initTS = import_path35.default.join(projectRoot, `${fileName}.ts`);
18927
- if (import_fs25.default.existsSync(initTS)) {
18928
- const initJSWithExt = import_path35.default.join(outDir, `${fileName}.mjs`);
19436
+ const initTS = import_path38.default.join(projectRoot, `${fileName}.ts`);
19437
+ if (import_fs27.default.existsSync(initTS)) {
19438
+ const initJSWithExt = import_path38.default.join(outDir, `${fileName}.mjs`);
18929
19439
  await import_esbuild.default.build({
18930
19440
  entryPoints: [initTS],
18931
19441
  outfile: initJSWithExt,
@@ -18937,7 +19447,7 @@ async function buildServerApp(projectRoot, appDir, config) {
18937
19447
  bundle: true,
18938
19448
  packages: "external",
18939
19449
  logLevel: "info",
18940
- tsconfig: import_path35.default.join(projectRoot, "tsconfig.json"),
19450
+ tsconfig: import_path38.default.join(projectRoot, "tsconfig.json"),
18941
19451
  plugins: [pathAliasPlugin],
18942
19452
  outExtension: { ".js": ".mjs" }
18943
19453
  });
@@ -18953,8 +19463,8 @@ async function buildApp(options = {}) {
18953
19463
  const config = options.config ?? loadConfig(projectRoot);
18954
19464
  const appDir = options.appDir ?? getAppDir(projectRoot, config);
18955
19465
  try {
18956
- const tsxPath = import_path36.default.join(projectRoot, "node_modules", "tsx", "dist", "esm", "index.mjs");
18957
- if (import_fs26.default.existsSync(tsxPath)) {
19466
+ const tsxPath = import_path39.default.join(projectRoot, "node_modules", "tsx", "dist", "esm", "index.mjs");
19467
+ if (import_fs28.default.existsSync(tsxPath)) {
18958
19468
  const { pathToFileURL: pathToFileURL2 } = await import("url");
18959
19469
  const tsxUrl = pathToFileURL2(tsxPath).href;
18960
19470
  await import(tsxUrl);
@@ -19223,132 +19733,134 @@ function getOrCreateLink(rel, href) {
19223
19733
  }
19224
19734
  function applyMetadata(md) {
19225
19735
  if (!md) return;
19226
- if (md.title) {
19227
- document.title = md.title;
19228
- }
19229
- if (md.description) {
19230
- const meta = getOrCreateMeta('meta[name="description"]', { name: "description" });
19231
- meta.content = md.description;
19232
- }
19233
- if (md.robots) {
19234
- const meta = getOrCreateMeta('meta[name="robots"]', { name: "robots" });
19235
- meta.content = md.robots;
19236
- }
19237
- if (md.themeColor) {
19238
- const meta = getOrCreateMeta('meta[name="theme-color"]', { name: "theme-color" });
19239
- meta.content = md.themeColor;
19240
- }
19241
- if (md.viewport) {
19242
- const meta = getOrCreateMeta('meta[name="viewport"]', { name: "viewport" });
19243
- meta.content = md.viewport;
19244
- }
19245
- if (md.canonical) {
19246
- getOrCreateLink("canonical", md.canonical);
19247
- }
19248
- if (md.openGraph) {
19249
- const og = md.openGraph;
19250
- if (og.title) {
19251
- const meta = getOrCreateMeta('meta[property="og:title"]', { property: "og:title" });
19252
- meta.content = og.title;
19253
- }
19254
- if (og.description) {
19255
- const meta = getOrCreateMeta('meta[property="og:description"]', { property: "og:description" });
19256
- meta.content = og.description;
19257
- }
19258
- if (og.type) {
19259
- const meta = getOrCreateMeta('meta[property="og:type"]', { property: "og:type" });
19260
- meta.content = og.type;
19261
- }
19262
- if (og.url) {
19263
- const meta = getOrCreateMeta('meta[property="og:url"]', { property: "og:url" });
19264
- meta.content = og.url;
19265
- }
19266
- if (og.image) {
19267
- if (typeof og.image === "string") {
19268
- const meta = getOrCreateMeta('meta[property="og:image"]', { property: "og:image" });
19269
- meta.content = og.image;
19270
- } else {
19271
- const meta = getOrCreateMeta('meta[property="og:image"]', { property: "og:image" });
19272
- meta.content = og.image.url;
19273
- if (og.image.width) {
19274
- const metaWidth = getOrCreateMeta('meta[property="og:image:width"]', { property: "og:image:width" });
19275
- metaWidth.content = String(og.image.width);
19276
- }
19277
- if (og.image.height) {
19278
- const metaHeight = getOrCreateMeta('meta[property="og:image:height"]', { property: "og:image:height" });
19279
- metaHeight.content = String(og.image.height);
19280
- }
19281
- if (og.image.alt) {
19282
- const metaAlt = getOrCreateMeta('meta[property="og:image:alt"]', { property: "og:image:alt" });
19283
- metaAlt.content = og.image.alt;
19736
+ requestAnimationFrame(() => {
19737
+ if (md.title) {
19738
+ document.title = md.title;
19739
+ }
19740
+ if (md.description) {
19741
+ const meta = getOrCreateMeta('meta[name="description"]', { name: "description" });
19742
+ meta.content = md.description;
19743
+ }
19744
+ if (md.robots) {
19745
+ const meta = getOrCreateMeta('meta[name="robots"]', { name: "robots" });
19746
+ meta.content = md.robots;
19747
+ }
19748
+ if (md.themeColor) {
19749
+ const meta = getOrCreateMeta('meta[name="theme-color"]', { name: "theme-color" });
19750
+ meta.content = md.themeColor;
19751
+ }
19752
+ if (md.viewport) {
19753
+ const meta = getOrCreateMeta('meta[name="viewport"]', { name: "viewport" });
19754
+ meta.content = md.viewport;
19755
+ }
19756
+ if (md.canonical) {
19757
+ getOrCreateLink("canonical", md.canonical);
19758
+ }
19759
+ if (md.openGraph) {
19760
+ const og = md.openGraph;
19761
+ if (og.title) {
19762
+ const meta = getOrCreateMeta('meta[property="og:title"]', { property: "og:title" });
19763
+ meta.content = og.title;
19764
+ }
19765
+ if (og.description) {
19766
+ const meta = getOrCreateMeta('meta[property="og:description"]', { property: "og:description" });
19767
+ meta.content = og.description;
19768
+ }
19769
+ if (og.type) {
19770
+ const meta = getOrCreateMeta('meta[property="og:type"]', { property: "og:type" });
19771
+ meta.content = og.type;
19772
+ }
19773
+ if (og.url) {
19774
+ const meta = getOrCreateMeta('meta[property="og:url"]', { property: "og:url" });
19775
+ meta.content = og.url;
19776
+ }
19777
+ if (og.image) {
19778
+ if (typeof og.image === "string") {
19779
+ const meta = getOrCreateMeta('meta[property="og:image"]', { property: "og:image" });
19780
+ meta.content = og.image;
19781
+ } else {
19782
+ const meta = getOrCreateMeta('meta[property="og:image"]', { property: "og:image" });
19783
+ meta.content = og.image.url;
19784
+ if (og.image.width) {
19785
+ const metaWidth = getOrCreateMeta('meta[property="og:image:width"]', { property: "og:image:width" });
19786
+ metaWidth.content = String(og.image.width);
19787
+ }
19788
+ if (og.image.height) {
19789
+ const metaHeight = getOrCreateMeta('meta[property="og:image:height"]', { property: "og:image:height" });
19790
+ metaHeight.content = String(og.image.height);
19791
+ }
19792
+ if (og.image.alt) {
19793
+ const metaAlt = getOrCreateMeta('meta[property="og:image:alt"]', { property: "og:image:alt" });
19794
+ metaAlt.content = og.image.alt;
19795
+ }
19284
19796
  }
19285
19797
  }
19798
+ if (og.siteName) {
19799
+ const meta = getOrCreateMeta('meta[property="og:site_name"]', { property: "og:site_name" });
19800
+ meta.content = og.siteName;
19801
+ }
19802
+ if (og.locale) {
19803
+ const meta = getOrCreateMeta('meta[property="og:locale"]', { property: "og:locale" });
19804
+ meta.content = og.locale;
19805
+ }
19286
19806
  }
19287
- if (og.siteName) {
19288
- const meta = getOrCreateMeta('meta[property="og:site_name"]', { property: "og:site_name" });
19289
- meta.content = og.siteName;
19290
- }
19291
- if (og.locale) {
19292
- const meta = getOrCreateMeta('meta[property="og:locale"]', { property: "og:locale" });
19293
- meta.content = og.locale;
19294
- }
19295
- }
19296
- if (md.twitter) {
19297
- const twitter = md.twitter;
19298
- if (twitter.card) {
19299
- const meta = getOrCreateMeta('meta[name="twitter:card"]', { name: "twitter:card" });
19300
- meta.content = twitter.card;
19301
- }
19302
- if (twitter.title) {
19303
- const meta = getOrCreateMeta('meta[name="twitter:title"]', { name: "twitter:title" });
19304
- meta.content = twitter.title;
19305
- }
19306
- if (twitter.description) {
19307
- const meta = getOrCreateMeta('meta[name="twitter:description"]', { name: "twitter:description" });
19308
- meta.content = twitter.description;
19309
- }
19310
- if (twitter.image) {
19311
- const meta = getOrCreateMeta('meta[name="twitter:image"]', { name: "twitter:image" });
19312
- meta.content = twitter.image;
19807
+ if (md.twitter) {
19808
+ const twitter = md.twitter;
19809
+ if (twitter.card) {
19810
+ const meta = getOrCreateMeta('meta[name="twitter:card"]', { name: "twitter:card" });
19811
+ meta.content = twitter.card;
19812
+ }
19813
+ if (twitter.title) {
19814
+ const meta = getOrCreateMeta('meta[name="twitter:title"]', { name: "twitter:title" });
19815
+ meta.content = twitter.title;
19816
+ }
19817
+ if (twitter.description) {
19818
+ const meta = getOrCreateMeta('meta[name="twitter:description"]', { name: "twitter:description" });
19819
+ meta.content = twitter.description;
19820
+ }
19821
+ if (twitter.image) {
19822
+ const meta = getOrCreateMeta('meta[name="twitter:image"]', { name: "twitter:image" });
19823
+ meta.content = twitter.image;
19824
+ }
19825
+ if (twitter.imageAlt) {
19826
+ const meta = getOrCreateMeta('meta[name="twitter:image:alt"]', { name: "twitter:image:alt" });
19827
+ meta.content = twitter.imageAlt;
19828
+ }
19829
+ if (twitter.site) {
19830
+ const meta = getOrCreateMeta('meta[name="twitter:site"]', { name: "twitter:site" });
19831
+ meta.content = twitter.site;
19832
+ }
19833
+ if (twitter.creator) {
19834
+ const meta = getOrCreateMeta('meta[name="twitter:creator"]', { name: "twitter:creator" });
19835
+ meta.content = twitter.creator;
19836
+ }
19313
19837
  }
19314
- if (twitter.imageAlt) {
19315
- const meta = getOrCreateMeta('meta[name="twitter:image:alt"]', { name: "twitter:image:alt" });
19316
- meta.content = twitter.imageAlt;
19838
+ if (md.metaTags && Array.isArray(md.metaTags)) {
19839
+ md.metaTags.forEach((tag) => {
19840
+ let selector = "";
19841
+ if (tag.name) {
19842
+ selector = `meta[name="${tag.name}"]`;
19843
+ } else if (tag.property) {
19844
+ selector = `meta[property="${tag.property}"]`;
19845
+ } else if (tag.httpEquiv) {
19846
+ selector = `meta[http-equiv="${tag.httpEquiv}"]`;
19847
+ }
19848
+ if (selector) {
19849
+ const meta = getOrCreateMeta(selector, {
19850
+ name: tag.name,
19851
+ property: tag.property,
19852
+ httpEquiv: tag.httpEquiv
19853
+ });
19854
+ meta.content = tag.content;
19855
+ }
19856
+ });
19317
19857
  }
19318
- if (twitter.site) {
19319
- const meta = getOrCreateMeta('meta[name="twitter:site"]', { name: "twitter:site" });
19320
- meta.content = twitter.site;
19858
+ if (md.links && Array.isArray(md.links)) {
19859
+ md.links.forEach((link) => {
19860
+ getOrCreateLink(link.rel, link.href);
19861
+ });
19321
19862
  }
19322
- if (twitter.creator) {
19323
- const meta = getOrCreateMeta('meta[name="twitter:creator"]', { name: "twitter:creator" });
19324
- meta.content = twitter.creator;
19325
- }
19326
- }
19327
- if (md.metaTags && Array.isArray(md.metaTags)) {
19328
- md.metaTags.forEach((tag) => {
19329
- let selector = "";
19330
- if (tag.name) {
19331
- selector = `meta[name="${tag.name}"]`;
19332
- } else if (tag.property) {
19333
- selector = `meta[property="${tag.property}"]`;
19334
- } else if (tag.httpEquiv) {
19335
- selector = `meta[http-equiv="${tag.httpEquiv}"]`;
19336
- }
19337
- if (selector) {
19338
- const meta = getOrCreateMeta(selector, {
19339
- name: tag.name,
19340
- property: tag.property,
19341
- httpEquiv: tag.httpEquiv
19342
- });
19343
- meta.content = tag.content;
19344
- }
19345
- });
19346
- }
19347
- if (md.links && Array.isArray(md.links)) {
19348
- md.links.forEach((link) => {
19349
- getOrCreateLink(link.rel, link.href);
19350
- });
19351
- }
19863
+ });
19352
19864
  }
19353
19865
 
19354
19866
  // modules/runtime/client/AppShell.tsx
@@ -20238,11 +20750,11 @@ var ValidationError = class extends Error {
20238
20750
  format() {
20239
20751
  const formatted = {};
20240
20752
  for (const error of this.errors) {
20241
- const path33 = error.path.join(".");
20242
- if (!formatted[path33]) {
20243
- formatted[path33] = [];
20753
+ const path36 = error.path.join(".");
20754
+ if (!formatted[path36]) {
20755
+ formatted[path36] = [];
20244
20756
  }
20245
- formatted[path33].push(error.message);
20757
+ formatted[path36].push(error.message);
20246
20758
  }
20247
20759
  return formatted;
20248
20760
  }