@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/README.md +74 -0
- package/dist/cli.cjs +672 -162
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +672 -162
- package/dist/cli.mjs.map +1 -1
- package/dist/index.cjs +867 -355
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +26 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.mjs +867 -355
- package/dist/index.mjs.map +1 -1
- package/dist/react/components.cjs +122 -5
- package/dist/react/components.cjs.map +1 -1
- package/dist/react/components.d.mts +18 -4
- package/dist/react/components.d.ts +18 -4
- package/dist/react/components.mjs +123 -6
- package/dist/react/components.mjs.map +1 -1
- package/dist/runtime.cjs +118 -116
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.mjs +118 -116
- package/dist/runtime.mjs.map +1 -1
- package/package.json +3 -1
package/dist/index.mjs
CHANGED
|
@@ -9957,8 +9957,8 @@ var require_built3 = __commonJS({
|
|
|
9957
9957
|
});
|
|
9958
9958
|
|
|
9959
9959
|
// src/server.ts
|
|
9960
|
-
import
|
|
9961
|
-
import
|
|
9960
|
+
import fs23 from "fs";
|
|
9961
|
+
import path30 from "path";
|
|
9962
9962
|
|
|
9963
9963
|
// modules/server/utils/server-dir.ts
|
|
9964
9964
|
init_globals();
|
|
@@ -11794,6 +11794,7 @@ async function processRewrites(urlPath, compiledRewrites, req) {
|
|
|
11794
11794
|
const normalizedPath = urlPath.replace(/\/$/, "") || "/";
|
|
11795
11795
|
if (normalizedPath.startsWith("/static/") || // Static assets (client.js, client.css, etc.)
|
|
11796
11796
|
normalizedPath.startsWith("/__fw/") || // Framework internal routes (hot reload, etc.)
|
|
11797
|
+
normalizedPath.startsWith("/_loly/") || // Framework internal routes (image optimization, etc.)
|
|
11797
11798
|
normalizedPath === "/favicon.ico" || // Favicon
|
|
11798
11799
|
normalizedPath.startsWith("/wss/")) {
|
|
11799
11800
|
if (process.env.NODE_ENV === "development") {
|
|
@@ -12703,7 +12704,7 @@ var ReaddirpStream = class extends Readable {
|
|
|
12703
12704
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
12704
12705
|
const statMethod = opts.lstat ? lstat : stat;
|
|
12705
12706
|
if (wantBigintFsStats) {
|
|
12706
|
-
this._stat = (
|
|
12707
|
+
this._stat = (path36) => statMethod(path36, { bigint: true });
|
|
12707
12708
|
} else {
|
|
12708
12709
|
this._stat = statMethod;
|
|
12709
12710
|
}
|
|
@@ -12728,8 +12729,8 @@ var ReaddirpStream = class extends Readable {
|
|
|
12728
12729
|
const par = this.parent;
|
|
12729
12730
|
const fil = par && par.files;
|
|
12730
12731
|
if (fil && fil.length > 0) {
|
|
12731
|
-
const { path:
|
|
12732
|
-
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent,
|
|
12732
|
+
const { path: path36, depth } = par;
|
|
12733
|
+
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path36));
|
|
12733
12734
|
const awaited = await Promise.all(slice);
|
|
12734
12735
|
for (const entry of awaited) {
|
|
12735
12736
|
if (!entry)
|
|
@@ -12769,20 +12770,20 @@ var ReaddirpStream = class extends Readable {
|
|
|
12769
12770
|
this.reading = false;
|
|
12770
12771
|
}
|
|
12771
12772
|
}
|
|
12772
|
-
async _exploreDir(
|
|
12773
|
+
async _exploreDir(path36, depth) {
|
|
12773
12774
|
let files;
|
|
12774
12775
|
try {
|
|
12775
|
-
files = await readdir(
|
|
12776
|
+
files = await readdir(path36, this._rdOptions);
|
|
12776
12777
|
} catch (error) {
|
|
12777
12778
|
this._onError(error);
|
|
12778
12779
|
}
|
|
12779
|
-
return { files, depth, path:
|
|
12780
|
+
return { files, depth, path: path36 };
|
|
12780
12781
|
}
|
|
12781
|
-
async _formatEntry(dirent,
|
|
12782
|
+
async _formatEntry(dirent, path36) {
|
|
12782
12783
|
let entry;
|
|
12783
12784
|
const basename3 = this._isDirent ? dirent.name : dirent;
|
|
12784
12785
|
try {
|
|
12785
|
-
const fullPath = presolve(pjoin(
|
|
12786
|
+
const fullPath = presolve(pjoin(path36, basename3));
|
|
12786
12787
|
entry = { path: prelative(this._root, fullPath), fullPath, basename: basename3 };
|
|
12787
12788
|
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
12788
12789
|
} catch (err) {
|
|
@@ -13182,16 +13183,16 @@ var delFromSet = (main, prop, item) => {
|
|
|
13182
13183
|
};
|
|
13183
13184
|
var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
|
|
13184
13185
|
var FsWatchInstances = /* @__PURE__ */ new Map();
|
|
13185
|
-
function createFsWatchInstance(
|
|
13186
|
+
function createFsWatchInstance(path36, options, listener, errHandler, emitRaw) {
|
|
13186
13187
|
const handleEvent = (rawEvent, evPath) => {
|
|
13187
|
-
listener(
|
|
13188
|
-
emitRaw(rawEvent, evPath, { watchedPath:
|
|
13189
|
-
if (evPath &&
|
|
13190
|
-
fsWatchBroadcast(sysPath.resolve(
|
|
13188
|
+
listener(path36);
|
|
13189
|
+
emitRaw(rawEvent, evPath, { watchedPath: path36 });
|
|
13190
|
+
if (evPath && path36 !== evPath) {
|
|
13191
|
+
fsWatchBroadcast(sysPath.resolve(path36, evPath), KEY_LISTENERS, sysPath.join(path36, evPath));
|
|
13191
13192
|
}
|
|
13192
13193
|
};
|
|
13193
13194
|
try {
|
|
13194
|
-
return fs_watch(
|
|
13195
|
+
return fs_watch(path36, {
|
|
13195
13196
|
persistent: options.persistent
|
|
13196
13197
|
}, handleEvent);
|
|
13197
13198
|
} catch (error) {
|
|
@@ -13207,12 +13208,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
|
|
|
13207
13208
|
listener(val1, val2, val3);
|
|
13208
13209
|
});
|
|
13209
13210
|
};
|
|
13210
|
-
var setFsWatchListener = (
|
|
13211
|
+
var setFsWatchListener = (path36, fullPath, options, handlers) => {
|
|
13211
13212
|
const { listener, errHandler, rawEmitter } = handlers;
|
|
13212
13213
|
let cont = FsWatchInstances.get(fullPath);
|
|
13213
13214
|
let watcher;
|
|
13214
13215
|
if (!options.persistent) {
|
|
13215
|
-
watcher = createFsWatchInstance(
|
|
13216
|
+
watcher = createFsWatchInstance(path36, options, listener, errHandler, rawEmitter);
|
|
13216
13217
|
if (!watcher)
|
|
13217
13218
|
return;
|
|
13218
13219
|
return watcher.close.bind(watcher);
|
|
@@ -13223,7 +13224,7 @@ var setFsWatchListener = (path33, fullPath, options, handlers) => {
|
|
|
13223
13224
|
addAndConvert(cont, KEY_RAW, rawEmitter);
|
|
13224
13225
|
} else {
|
|
13225
13226
|
watcher = createFsWatchInstance(
|
|
13226
|
-
|
|
13227
|
+
path36,
|
|
13227
13228
|
options,
|
|
13228
13229
|
fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
|
|
13229
13230
|
errHandler,
|
|
@@ -13238,7 +13239,7 @@ var setFsWatchListener = (path33, fullPath, options, handlers) => {
|
|
|
13238
13239
|
cont.watcherUnusable = true;
|
|
13239
13240
|
if (isWindows && error.code === "EPERM") {
|
|
13240
13241
|
try {
|
|
13241
|
-
const fd = await open(
|
|
13242
|
+
const fd = await open(path36, "r");
|
|
13242
13243
|
await fd.close();
|
|
13243
13244
|
broadcastErr(error);
|
|
13244
13245
|
} catch (err) {
|
|
@@ -13269,7 +13270,7 @@ var setFsWatchListener = (path33, fullPath, options, handlers) => {
|
|
|
13269
13270
|
};
|
|
13270
13271
|
};
|
|
13271
13272
|
var FsWatchFileInstances = /* @__PURE__ */ new Map();
|
|
13272
|
-
var setFsWatchFileListener = (
|
|
13273
|
+
var setFsWatchFileListener = (path36, fullPath, options, handlers) => {
|
|
13273
13274
|
const { listener, rawEmitter } = handlers;
|
|
13274
13275
|
let cont = FsWatchFileInstances.get(fullPath);
|
|
13275
13276
|
const copts = cont && cont.options;
|
|
@@ -13291,7 +13292,7 @@ var setFsWatchFileListener = (path33, fullPath, options, handlers) => {
|
|
|
13291
13292
|
});
|
|
13292
13293
|
const currmtime = curr.mtimeMs;
|
|
13293
13294
|
if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
|
|
13294
|
-
foreach(cont.listeners, (listener2) => listener2(
|
|
13295
|
+
foreach(cont.listeners, (listener2) => listener2(path36, curr));
|
|
13295
13296
|
}
|
|
13296
13297
|
})
|
|
13297
13298
|
};
|
|
@@ -13319,13 +13320,13 @@ var NodeFsHandler = class {
|
|
|
13319
13320
|
* @param listener on fs change
|
|
13320
13321
|
* @returns closer for the watcher instance
|
|
13321
13322
|
*/
|
|
13322
|
-
_watchWithNodeFs(
|
|
13323
|
+
_watchWithNodeFs(path36, listener) {
|
|
13323
13324
|
const opts = this.fsw.options;
|
|
13324
|
-
const directory = sysPath.dirname(
|
|
13325
|
-
const basename3 = sysPath.basename(
|
|
13325
|
+
const directory = sysPath.dirname(path36);
|
|
13326
|
+
const basename3 = sysPath.basename(path36);
|
|
13326
13327
|
const parent = this.fsw._getWatchedDir(directory);
|
|
13327
13328
|
parent.add(basename3);
|
|
13328
|
-
const absolutePath = sysPath.resolve(
|
|
13329
|
+
const absolutePath = sysPath.resolve(path36);
|
|
13329
13330
|
const options = {
|
|
13330
13331
|
persistent: opts.persistent
|
|
13331
13332
|
};
|
|
@@ -13335,12 +13336,12 @@ var NodeFsHandler = class {
|
|
|
13335
13336
|
if (opts.usePolling) {
|
|
13336
13337
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
13337
13338
|
options.interval = enableBin && isBinaryPath(basename3) ? opts.binaryInterval : opts.interval;
|
|
13338
|
-
closer = setFsWatchFileListener(
|
|
13339
|
+
closer = setFsWatchFileListener(path36, absolutePath, options, {
|
|
13339
13340
|
listener,
|
|
13340
13341
|
rawEmitter: this.fsw._emitRaw
|
|
13341
13342
|
});
|
|
13342
13343
|
} else {
|
|
13343
|
-
closer = setFsWatchListener(
|
|
13344
|
+
closer = setFsWatchListener(path36, absolutePath, options, {
|
|
13344
13345
|
listener,
|
|
13345
13346
|
errHandler: this._boundHandleError,
|
|
13346
13347
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -13362,7 +13363,7 @@ var NodeFsHandler = class {
|
|
|
13362
13363
|
let prevStats = stats;
|
|
13363
13364
|
if (parent.has(basename3))
|
|
13364
13365
|
return;
|
|
13365
|
-
const listener = async (
|
|
13366
|
+
const listener = async (path36, newStats) => {
|
|
13366
13367
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
|
|
13367
13368
|
return;
|
|
13368
13369
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
@@ -13376,11 +13377,11 @@ var NodeFsHandler = class {
|
|
|
13376
13377
|
this.fsw._emit(EV.CHANGE, file, newStats2);
|
|
13377
13378
|
}
|
|
13378
13379
|
if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
|
|
13379
|
-
this.fsw._closeFile(
|
|
13380
|
+
this.fsw._closeFile(path36);
|
|
13380
13381
|
prevStats = newStats2;
|
|
13381
13382
|
const closer2 = this._watchWithNodeFs(file, listener);
|
|
13382
13383
|
if (closer2)
|
|
13383
|
-
this.fsw._addPathCloser(
|
|
13384
|
+
this.fsw._addPathCloser(path36, closer2);
|
|
13384
13385
|
} else {
|
|
13385
13386
|
prevStats = newStats2;
|
|
13386
13387
|
}
|
|
@@ -13412,7 +13413,7 @@ var NodeFsHandler = class {
|
|
|
13412
13413
|
* @param item basename of this item
|
|
13413
13414
|
* @returns true if no more processing is needed for this entry.
|
|
13414
13415
|
*/
|
|
13415
|
-
async _handleSymlink(entry, directory,
|
|
13416
|
+
async _handleSymlink(entry, directory, path36, item) {
|
|
13416
13417
|
if (this.fsw.closed) {
|
|
13417
13418
|
return;
|
|
13418
13419
|
}
|
|
@@ -13422,7 +13423,7 @@ var NodeFsHandler = class {
|
|
|
13422
13423
|
this.fsw._incrReadyCount();
|
|
13423
13424
|
let linkPath;
|
|
13424
13425
|
try {
|
|
13425
|
-
linkPath = await fsrealpath(
|
|
13426
|
+
linkPath = await fsrealpath(path36);
|
|
13426
13427
|
} catch (e) {
|
|
13427
13428
|
this.fsw._emitReady();
|
|
13428
13429
|
return true;
|
|
@@ -13432,12 +13433,12 @@ var NodeFsHandler = class {
|
|
|
13432
13433
|
if (dir.has(item)) {
|
|
13433
13434
|
if (this.fsw._symlinkPaths.get(full) !== linkPath) {
|
|
13434
13435
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
13435
|
-
this.fsw._emit(EV.CHANGE,
|
|
13436
|
+
this.fsw._emit(EV.CHANGE, path36, entry.stats);
|
|
13436
13437
|
}
|
|
13437
13438
|
} else {
|
|
13438
13439
|
dir.add(item);
|
|
13439
13440
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
13440
|
-
this.fsw._emit(EV.ADD,
|
|
13441
|
+
this.fsw._emit(EV.ADD, path36, entry.stats);
|
|
13441
13442
|
}
|
|
13442
13443
|
this.fsw._emitReady();
|
|
13443
13444
|
return true;
|
|
@@ -13466,9 +13467,9 @@ var NodeFsHandler = class {
|
|
|
13466
13467
|
return;
|
|
13467
13468
|
}
|
|
13468
13469
|
const item = entry.path;
|
|
13469
|
-
let
|
|
13470
|
+
let path36 = sysPath.join(directory, item);
|
|
13470
13471
|
current.add(item);
|
|
13471
|
-
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory,
|
|
13472
|
+
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path36, item)) {
|
|
13472
13473
|
return;
|
|
13473
13474
|
}
|
|
13474
13475
|
if (this.fsw.closed) {
|
|
@@ -13477,8 +13478,8 @@ var NodeFsHandler = class {
|
|
|
13477
13478
|
}
|
|
13478
13479
|
if (item === target || !target && !previous.has(item)) {
|
|
13479
13480
|
this.fsw._incrReadyCount();
|
|
13480
|
-
|
|
13481
|
-
this._addToNodeFs(
|
|
13481
|
+
path36 = sysPath.join(dir, sysPath.relative(dir, path36));
|
|
13482
|
+
this._addToNodeFs(path36, initialAdd, wh, depth + 1);
|
|
13482
13483
|
}
|
|
13483
13484
|
}).on(EV.ERROR, this._boundHandleError);
|
|
13484
13485
|
return new Promise((resolve3, reject) => {
|
|
@@ -13547,13 +13548,13 @@ var NodeFsHandler = class {
|
|
|
13547
13548
|
* @param depth Child path actually targeted for watch
|
|
13548
13549
|
* @param target Child path actually targeted for watch
|
|
13549
13550
|
*/
|
|
13550
|
-
async _addToNodeFs(
|
|
13551
|
+
async _addToNodeFs(path36, initialAdd, priorWh, depth, target) {
|
|
13551
13552
|
const ready = this.fsw._emitReady;
|
|
13552
|
-
if (this.fsw._isIgnored(
|
|
13553
|
+
if (this.fsw._isIgnored(path36) || this.fsw.closed) {
|
|
13553
13554
|
ready();
|
|
13554
13555
|
return false;
|
|
13555
13556
|
}
|
|
13556
|
-
const wh = this.fsw._getWatchHelpers(
|
|
13557
|
+
const wh = this.fsw._getWatchHelpers(path36);
|
|
13557
13558
|
if (priorWh) {
|
|
13558
13559
|
wh.filterPath = (entry) => priorWh.filterPath(entry);
|
|
13559
13560
|
wh.filterDir = (entry) => priorWh.filterDir(entry);
|
|
@@ -13569,8 +13570,8 @@ var NodeFsHandler = class {
|
|
|
13569
13570
|
const follow = this.fsw.options.followSymlinks;
|
|
13570
13571
|
let closer;
|
|
13571
13572
|
if (stats.isDirectory()) {
|
|
13572
|
-
const absPath = sysPath.resolve(
|
|
13573
|
-
const targetPath = follow ? await fsrealpath(
|
|
13573
|
+
const absPath = sysPath.resolve(path36);
|
|
13574
|
+
const targetPath = follow ? await fsrealpath(path36) : path36;
|
|
13574
13575
|
if (this.fsw.closed)
|
|
13575
13576
|
return;
|
|
13576
13577
|
closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
|
|
@@ -13580,29 +13581,29 @@ var NodeFsHandler = class {
|
|
|
13580
13581
|
this.fsw._symlinkPaths.set(absPath, targetPath);
|
|
13581
13582
|
}
|
|
13582
13583
|
} else if (stats.isSymbolicLink()) {
|
|
13583
|
-
const targetPath = follow ? await fsrealpath(
|
|
13584
|
+
const targetPath = follow ? await fsrealpath(path36) : path36;
|
|
13584
13585
|
if (this.fsw.closed)
|
|
13585
13586
|
return;
|
|
13586
13587
|
const parent = sysPath.dirname(wh.watchPath);
|
|
13587
13588
|
this.fsw._getWatchedDir(parent).add(wh.watchPath);
|
|
13588
13589
|
this.fsw._emit(EV.ADD, wh.watchPath, stats);
|
|
13589
|
-
closer = await this._handleDir(parent, stats, initialAdd, depth,
|
|
13590
|
+
closer = await this._handleDir(parent, stats, initialAdd, depth, path36, wh, targetPath);
|
|
13590
13591
|
if (this.fsw.closed)
|
|
13591
13592
|
return;
|
|
13592
13593
|
if (targetPath !== void 0) {
|
|
13593
|
-
this.fsw._symlinkPaths.set(sysPath.resolve(
|
|
13594
|
+
this.fsw._symlinkPaths.set(sysPath.resolve(path36), targetPath);
|
|
13594
13595
|
}
|
|
13595
13596
|
} else {
|
|
13596
13597
|
closer = this._handleFile(wh.watchPath, stats, initialAdd);
|
|
13597
13598
|
}
|
|
13598
13599
|
ready();
|
|
13599
13600
|
if (closer)
|
|
13600
|
-
this.fsw._addPathCloser(
|
|
13601
|
+
this.fsw._addPathCloser(path36, closer);
|
|
13601
13602
|
return false;
|
|
13602
13603
|
} catch (error) {
|
|
13603
13604
|
if (this.fsw._handleError(error)) {
|
|
13604
13605
|
ready();
|
|
13605
|
-
return
|
|
13606
|
+
return path36;
|
|
13606
13607
|
}
|
|
13607
13608
|
}
|
|
13608
13609
|
}
|
|
@@ -13645,26 +13646,26 @@ function createPattern(matcher) {
|
|
|
13645
13646
|
}
|
|
13646
13647
|
return () => false;
|
|
13647
13648
|
}
|
|
13648
|
-
function normalizePath(
|
|
13649
|
-
if (typeof
|
|
13649
|
+
function normalizePath(path36) {
|
|
13650
|
+
if (typeof path36 !== "string")
|
|
13650
13651
|
throw new Error("string expected");
|
|
13651
|
-
|
|
13652
|
-
|
|
13652
|
+
path36 = sysPath2.normalize(path36);
|
|
13653
|
+
path36 = path36.replace(/\\/g, "/");
|
|
13653
13654
|
let prepend = false;
|
|
13654
|
-
if (
|
|
13655
|
+
if (path36.startsWith("//"))
|
|
13655
13656
|
prepend = true;
|
|
13656
13657
|
const DOUBLE_SLASH_RE2 = /\/\//;
|
|
13657
|
-
while (
|
|
13658
|
-
|
|
13658
|
+
while (path36.match(DOUBLE_SLASH_RE2))
|
|
13659
|
+
path36 = path36.replace(DOUBLE_SLASH_RE2, "/");
|
|
13659
13660
|
if (prepend)
|
|
13660
|
-
|
|
13661
|
-
return
|
|
13661
|
+
path36 = "/" + path36;
|
|
13662
|
+
return path36;
|
|
13662
13663
|
}
|
|
13663
13664
|
function matchPatterns(patterns, testString, stats) {
|
|
13664
|
-
const
|
|
13665
|
+
const path36 = normalizePath(testString);
|
|
13665
13666
|
for (let index = 0; index < patterns.length; index++) {
|
|
13666
13667
|
const pattern = patterns[index];
|
|
13667
|
-
if (pattern(
|
|
13668
|
+
if (pattern(path36, stats)) {
|
|
13668
13669
|
return true;
|
|
13669
13670
|
}
|
|
13670
13671
|
}
|
|
@@ -13704,19 +13705,19 @@ var toUnix = (string) => {
|
|
|
13704
13705
|
}
|
|
13705
13706
|
return str;
|
|
13706
13707
|
};
|
|
13707
|
-
var normalizePathToUnix = (
|
|
13708
|
-
var normalizeIgnored = (cwd = "") => (
|
|
13709
|
-
if (typeof
|
|
13710
|
-
return normalizePathToUnix(sysPath2.isAbsolute(
|
|
13708
|
+
var normalizePathToUnix = (path36) => toUnix(sysPath2.normalize(toUnix(path36)));
|
|
13709
|
+
var normalizeIgnored = (cwd = "") => (path36) => {
|
|
13710
|
+
if (typeof path36 === "string") {
|
|
13711
|
+
return normalizePathToUnix(sysPath2.isAbsolute(path36) ? path36 : sysPath2.join(cwd, path36));
|
|
13711
13712
|
} else {
|
|
13712
|
-
return
|
|
13713
|
+
return path36;
|
|
13713
13714
|
}
|
|
13714
13715
|
};
|
|
13715
|
-
var getAbsolutePath = (
|
|
13716
|
-
if (sysPath2.isAbsolute(
|
|
13717
|
-
return
|
|
13716
|
+
var getAbsolutePath = (path36, cwd) => {
|
|
13717
|
+
if (sysPath2.isAbsolute(path36)) {
|
|
13718
|
+
return path36;
|
|
13718
13719
|
}
|
|
13719
|
-
return sysPath2.join(cwd,
|
|
13720
|
+
return sysPath2.join(cwd, path36);
|
|
13720
13721
|
};
|
|
13721
13722
|
var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
|
|
13722
13723
|
var DirEntry = class {
|
|
@@ -13771,10 +13772,10 @@ var DirEntry = class {
|
|
|
13771
13772
|
var STAT_METHOD_F = "stat";
|
|
13772
13773
|
var STAT_METHOD_L = "lstat";
|
|
13773
13774
|
var WatchHelper = class {
|
|
13774
|
-
constructor(
|
|
13775
|
+
constructor(path36, follow, fsw) {
|
|
13775
13776
|
this.fsw = fsw;
|
|
13776
|
-
const watchPath =
|
|
13777
|
-
this.path =
|
|
13777
|
+
const watchPath = path36;
|
|
13778
|
+
this.path = path36 = path36.replace(REPLACER_RE, "");
|
|
13778
13779
|
this.watchPath = watchPath;
|
|
13779
13780
|
this.fullWatchPath = sysPath2.resolve(watchPath);
|
|
13780
13781
|
this.dirParts = [];
|
|
@@ -13896,20 +13897,20 @@ var FSWatcher = class extends EventEmitter {
|
|
|
13896
13897
|
this._closePromise = void 0;
|
|
13897
13898
|
let paths = unifyPaths(paths_);
|
|
13898
13899
|
if (cwd) {
|
|
13899
|
-
paths = paths.map((
|
|
13900
|
-
const absPath = getAbsolutePath(
|
|
13900
|
+
paths = paths.map((path36) => {
|
|
13901
|
+
const absPath = getAbsolutePath(path36, cwd);
|
|
13901
13902
|
return absPath;
|
|
13902
13903
|
});
|
|
13903
13904
|
}
|
|
13904
|
-
paths.forEach((
|
|
13905
|
-
this._removeIgnoredPath(
|
|
13905
|
+
paths.forEach((path36) => {
|
|
13906
|
+
this._removeIgnoredPath(path36);
|
|
13906
13907
|
});
|
|
13907
13908
|
this._userIgnored = void 0;
|
|
13908
13909
|
if (!this._readyCount)
|
|
13909
13910
|
this._readyCount = 0;
|
|
13910
13911
|
this._readyCount += paths.length;
|
|
13911
|
-
Promise.all(paths.map(async (
|
|
13912
|
-
const res = await this._nodeFsHandler._addToNodeFs(
|
|
13912
|
+
Promise.all(paths.map(async (path36) => {
|
|
13913
|
+
const res = await this._nodeFsHandler._addToNodeFs(path36, !_internal, void 0, 0, _origAdd);
|
|
13913
13914
|
if (res)
|
|
13914
13915
|
this._emitReady();
|
|
13915
13916
|
return res;
|
|
@@ -13931,17 +13932,17 @@ var FSWatcher = class extends EventEmitter {
|
|
|
13931
13932
|
return this;
|
|
13932
13933
|
const paths = unifyPaths(paths_);
|
|
13933
13934
|
const { cwd } = this.options;
|
|
13934
|
-
paths.forEach((
|
|
13935
|
-
if (!sysPath2.isAbsolute(
|
|
13935
|
+
paths.forEach((path36) => {
|
|
13936
|
+
if (!sysPath2.isAbsolute(path36) && !this._closers.has(path36)) {
|
|
13936
13937
|
if (cwd)
|
|
13937
|
-
|
|
13938
|
-
|
|
13938
|
+
path36 = sysPath2.join(cwd, path36);
|
|
13939
|
+
path36 = sysPath2.resolve(path36);
|
|
13939
13940
|
}
|
|
13940
|
-
this._closePath(
|
|
13941
|
-
this._addIgnoredPath(
|
|
13942
|
-
if (this._watched.has(
|
|
13941
|
+
this._closePath(path36);
|
|
13942
|
+
this._addIgnoredPath(path36);
|
|
13943
|
+
if (this._watched.has(path36)) {
|
|
13943
13944
|
this._addIgnoredPath({
|
|
13944
|
-
path:
|
|
13945
|
+
path: path36,
|
|
13945
13946
|
recursive: true
|
|
13946
13947
|
});
|
|
13947
13948
|
}
|
|
@@ -14005,38 +14006,38 @@ var FSWatcher = class extends EventEmitter {
|
|
|
14005
14006
|
* @param stats arguments to be passed with event
|
|
14006
14007
|
* @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
|
|
14007
14008
|
*/
|
|
14008
|
-
async _emit(event,
|
|
14009
|
+
async _emit(event, path36, stats) {
|
|
14009
14010
|
if (this.closed)
|
|
14010
14011
|
return;
|
|
14011
14012
|
const opts = this.options;
|
|
14012
14013
|
if (isWindows)
|
|
14013
|
-
|
|
14014
|
+
path36 = sysPath2.normalize(path36);
|
|
14014
14015
|
if (opts.cwd)
|
|
14015
|
-
|
|
14016
|
-
const args = [
|
|
14016
|
+
path36 = sysPath2.relative(opts.cwd, path36);
|
|
14017
|
+
const args = [path36];
|
|
14017
14018
|
if (stats != null)
|
|
14018
14019
|
args.push(stats);
|
|
14019
14020
|
const awf = opts.awaitWriteFinish;
|
|
14020
14021
|
let pw;
|
|
14021
|
-
if (awf && (pw = this._pendingWrites.get(
|
|
14022
|
+
if (awf && (pw = this._pendingWrites.get(path36))) {
|
|
14022
14023
|
pw.lastChange = /* @__PURE__ */ new Date();
|
|
14023
14024
|
return this;
|
|
14024
14025
|
}
|
|
14025
14026
|
if (opts.atomic) {
|
|
14026
14027
|
if (event === EVENTS.UNLINK) {
|
|
14027
|
-
this._pendingUnlinks.set(
|
|
14028
|
+
this._pendingUnlinks.set(path36, [event, ...args]);
|
|
14028
14029
|
setTimeout(() => {
|
|
14029
|
-
this._pendingUnlinks.forEach((entry,
|
|
14030
|
+
this._pendingUnlinks.forEach((entry, path37) => {
|
|
14030
14031
|
this.emit(...entry);
|
|
14031
14032
|
this.emit(EVENTS.ALL, ...entry);
|
|
14032
|
-
this._pendingUnlinks.delete(
|
|
14033
|
+
this._pendingUnlinks.delete(path37);
|
|
14033
14034
|
});
|
|
14034
14035
|
}, typeof opts.atomic === "number" ? opts.atomic : 100);
|
|
14035
14036
|
return this;
|
|
14036
14037
|
}
|
|
14037
|
-
if (event === EVENTS.ADD && this._pendingUnlinks.has(
|
|
14038
|
+
if (event === EVENTS.ADD && this._pendingUnlinks.has(path36)) {
|
|
14038
14039
|
event = EVENTS.CHANGE;
|
|
14039
|
-
this._pendingUnlinks.delete(
|
|
14040
|
+
this._pendingUnlinks.delete(path36);
|
|
14040
14041
|
}
|
|
14041
14042
|
}
|
|
14042
14043
|
if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
|
|
@@ -14054,16 +14055,16 @@ var FSWatcher = class extends EventEmitter {
|
|
|
14054
14055
|
this.emitWithAll(event, args);
|
|
14055
14056
|
}
|
|
14056
14057
|
};
|
|
14057
|
-
this._awaitWriteFinish(
|
|
14058
|
+
this._awaitWriteFinish(path36, awf.stabilityThreshold, event, awfEmit);
|
|
14058
14059
|
return this;
|
|
14059
14060
|
}
|
|
14060
14061
|
if (event === EVENTS.CHANGE) {
|
|
14061
|
-
const isThrottled = !this._throttle(EVENTS.CHANGE,
|
|
14062
|
+
const isThrottled = !this._throttle(EVENTS.CHANGE, path36, 50);
|
|
14062
14063
|
if (isThrottled)
|
|
14063
14064
|
return this;
|
|
14064
14065
|
}
|
|
14065
14066
|
if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
|
|
14066
|
-
const fullPath = opts.cwd ? sysPath2.join(opts.cwd,
|
|
14067
|
+
const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path36) : path36;
|
|
14067
14068
|
let stats2;
|
|
14068
14069
|
try {
|
|
14069
14070
|
stats2 = await stat3(fullPath);
|
|
@@ -14094,23 +14095,23 @@ var FSWatcher = class extends EventEmitter {
|
|
|
14094
14095
|
* @param timeout duration of time to suppress duplicate actions
|
|
14095
14096
|
* @returns tracking object or false if action should be suppressed
|
|
14096
14097
|
*/
|
|
14097
|
-
_throttle(actionType,
|
|
14098
|
+
_throttle(actionType, path36, timeout) {
|
|
14098
14099
|
if (!this._throttled.has(actionType)) {
|
|
14099
14100
|
this._throttled.set(actionType, /* @__PURE__ */ new Map());
|
|
14100
14101
|
}
|
|
14101
14102
|
const action = this._throttled.get(actionType);
|
|
14102
14103
|
if (!action)
|
|
14103
14104
|
throw new Error("invalid throttle");
|
|
14104
|
-
const actionPath = action.get(
|
|
14105
|
+
const actionPath = action.get(path36);
|
|
14105
14106
|
if (actionPath) {
|
|
14106
14107
|
actionPath.count++;
|
|
14107
14108
|
return false;
|
|
14108
14109
|
}
|
|
14109
14110
|
let timeoutObject;
|
|
14110
14111
|
const clear = () => {
|
|
14111
|
-
const item = action.get(
|
|
14112
|
+
const item = action.get(path36);
|
|
14112
14113
|
const count = item ? item.count : 0;
|
|
14113
|
-
action.delete(
|
|
14114
|
+
action.delete(path36);
|
|
14114
14115
|
clearTimeout(timeoutObject);
|
|
14115
14116
|
if (item)
|
|
14116
14117
|
clearTimeout(item.timeoutObject);
|
|
@@ -14118,7 +14119,7 @@ var FSWatcher = class extends EventEmitter {
|
|
|
14118
14119
|
};
|
|
14119
14120
|
timeoutObject = setTimeout(clear, timeout);
|
|
14120
14121
|
const thr = { timeoutObject, clear, count: 0 };
|
|
14121
|
-
action.set(
|
|
14122
|
+
action.set(path36, thr);
|
|
14122
14123
|
return thr;
|
|
14123
14124
|
}
|
|
14124
14125
|
_incrReadyCount() {
|
|
@@ -14132,44 +14133,44 @@ var FSWatcher = class extends EventEmitter {
|
|
|
14132
14133
|
* @param event
|
|
14133
14134
|
* @param awfEmit Callback to be called when ready for event to be emitted.
|
|
14134
14135
|
*/
|
|
14135
|
-
_awaitWriteFinish(
|
|
14136
|
+
_awaitWriteFinish(path36, threshold, event, awfEmit) {
|
|
14136
14137
|
const awf = this.options.awaitWriteFinish;
|
|
14137
14138
|
if (typeof awf !== "object")
|
|
14138
14139
|
return;
|
|
14139
14140
|
const pollInterval = awf.pollInterval;
|
|
14140
14141
|
let timeoutHandler;
|
|
14141
|
-
let fullPath =
|
|
14142
|
-
if (this.options.cwd && !sysPath2.isAbsolute(
|
|
14143
|
-
fullPath = sysPath2.join(this.options.cwd,
|
|
14142
|
+
let fullPath = path36;
|
|
14143
|
+
if (this.options.cwd && !sysPath2.isAbsolute(path36)) {
|
|
14144
|
+
fullPath = sysPath2.join(this.options.cwd, path36);
|
|
14144
14145
|
}
|
|
14145
14146
|
const now = /* @__PURE__ */ new Date();
|
|
14146
14147
|
const writes = this._pendingWrites;
|
|
14147
14148
|
function awaitWriteFinishFn(prevStat) {
|
|
14148
14149
|
statcb(fullPath, (err, curStat) => {
|
|
14149
|
-
if (err || !writes.has(
|
|
14150
|
+
if (err || !writes.has(path36)) {
|
|
14150
14151
|
if (err && err.code !== "ENOENT")
|
|
14151
14152
|
awfEmit(err);
|
|
14152
14153
|
return;
|
|
14153
14154
|
}
|
|
14154
14155
|
const now2 = Number(/* @__PURE__ */ new Date());
|
|
14155
14156
|
if (prevStat && curStat.size !== prevStat.size) {
|
|
14156
|
-
writes.get(
|
|
14157
|
+
writes.get(path36).lastChange = now2;
|
|
14157
14158
|
}
|
|
14158
|
-
const pw = writes.get(
|
|
14159
|
+
const pw = writes.get(path36);
|
|
14159
14160
|
const df = now2 - pw.lastChange;
|
|
14160
14161
|
if (df >= threshold) {
|
|
14161
|
-
writes.delete(
|
|
14162
|
+
writes.delete(path36);
|
|
14162
14163
|
awfEmit(void 0, curStat);
|
|
14163
14164
|
} else {
|
|
14164
14165
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
|
|
14165
14166
|
}
|
|
14166
14167
|
});
|
|
14167
14168
|
}
|
|
14168
|
-
if (!writes.has(
|
|
14169
|
-
writes.set(
|
|
14169
|
+
if (!writes.has(path36)) {
|
|
14170
|
+
writes.set(path36, {
|
|
14170
14171
|
lastChange: now,
|
|
14171
14172
|
cancelWait: () => {
|
|
14172
|
-
writes.delete(
|
|
14173
|
+
writes.delete(path36);
|
|
14173
14174
|
clearTimeout(timeoutHandler);
|
|
14174
14175
|
return event;
|
|
14175
14176
|
}
|
|
@@ -14180,8 +14181,8 @@ var FSWatcher = class extends EventEmitter {
|
|
|
14180
14181
|
/**
|
|
14181
14182
|
* Determines whether user has asked to ignore this path.
|
|
14182
14183
|
*/
|
|
14183
|
-
_isIgnored(
|
|
14184
|
-
if (this.options.atomic && DOT_RE.test(
|
|
14184
|
+
_isIgnored(path36, stats) {
|
|
14185
|
+
if (this.options.atomic && DOT_RE.test(path36))
|
|
14185
14186
|
return true;
|
|
14186
14187
|
if (!this._userIgnored) {
|
|
14187
14188
|
const { cwd } = this.options;
|
|
@@ -14191,17 +14192,17 @@ var FSWatcher = class extends EventEmitter {
|
|
|
14191
14192
|
const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
|
|
14192
14193
|
this._userIgnored = anymatch(list, void 0);
|
|
14193
14194
|
}
|
|
14194
|
-
return this._userIgnored(
|
|
14195
|
+
return this._userIgnored(path36, stats);
|
|
14195
14196
|
}
|
|
14196
|
-
_isntIgnored(
|
|
14197
|
-
return !this._isIgnored(
|
|
14197
|
+
_isntIgnored(path36, stat4) {
|
|
14198
|
+
return !this._isIgnored(path36, stat4);
|
|
14198
14199
|
}
|
|
14199
14200
|
/**
|
|
14200
14201
|
* Provides a set of common helpers and properties relating to symlink handling.
|
|
14201
14202
|
* @param path file or directory pattern being watched
|
|
14202
14203
|
*/
|
|
14203
|
-
_getWatchHelpers(
|
|
14204
|
-
return new WatchHelper(
|
|
14204
|
+
_getWatchHelpers(path36) {
|
|
14205
|
+
return new WatchHelper(path36, this.options.followSymlinks, this);
|
|
14205
14206
|
}
|
|
14206
14207
|
// Directory helpers
|
|
14207
14208
|
// -----------------
|
|
@@ -14233,63 +14234,63 @@ var FSWatcher = class extends EventEmitter {
|
|
|
14233
14234
|
* @param item base path of item/directory
|
|
14234
14235
|
*/
|
|
14235
14236
|
_remove(directory, item, isDirectory) {
|
|
14236
|
-
const
|
|
14237
|
-
const fullPath = sysPath2.resolve(
|
|
14238
|
-
isDirectory = isDirectory != null ? isDirectory : this._watched.has(
|
|
14239
|
-
if (!this._throttle("remove",
|
|
14237
|
+
const path36 = sysPath2.join(directory, item);
|
|
14238
|
+
const fullPath = sysPath2.resolve(path36);
|
|
14239
|
+
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path36) || this._watched.has(fullPath);
|
|
14240
|
+
if (!this._throttle("remove", path36, 100))
|
|
14240
14241
|
return;
|
|
14241
14242
|
if (!isDirectory && this._watched.size === 1) {
|
|
14242
14243
|
this.add(directory, item, true);
|
|
14243
14244
|
}
|
|
14244
|
-
const wp = this._getWatchedDir(
|
|
14245
|
+
const wp = this._getWatchedDir(path36);
|
|
14245
14246
|
const nestedDirectoryChildren = wp.getChildren();
|
|
14246
|
-
nestedDirectoryChildren.forEach((nested) => this._remove(
|
|
14247
|
+
nestedDirectoryChildren.forEach((nested) => this._remove(path36, nested));
|
|
14247
14248
|
const parent = this._getWatchedDir(directory);
|
|
14248
14249
|
const wasTracked = parent.has(item);
|
|
14249
14250
|
parent.remove(item);
|
|
14250
14251
|
if (this._symlinkPaths.has(fullPath)) {
|
|
14251
14252
|
this._symlinkPaths.delete(fullPath);
|
|
14252
14253
|
}
|
|
14253
|
-
let relPath =
|
|
14254
|
+
let relPath = path36;
|
|
14254
14255
|
if (this.options.cwd)
|
|
14255
|
-
relPath = sysPath2.relative(this.options.cwd,
|
|
14256
|
+
relPath = sysPath2.relative(this.options.cwd, path36);
|
|
14256
14257
|
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
14257
14258
|
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
14258
14259
|
if (event === EVENTS.ADD)
|
|
14259
14260
|
return;
|
|
14260
14261
|
}
|
|
14261
|
-
this._watched.delete(
|
|
14262
|
+
this._watched.delete(path36);
|
|
14262
14263
|
this._watched.delete(fullPath);
|
|
14263
14264
|
const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
|
|
14264
|
-
if (wasTracked && !this._isIgnored(
|
|
14265
|
-
this._emit(eventName,
|
|
14266
|
-
this._closePath(
|
|
14265
|
+
if (wasTracked && !this._isIgnored(path36))
|
|
14266
|
+
this._emit(eventName, path36);
|
|
14267
|
+
this._closePath(path36);
|
|
14267
14268
|
}
|
|
14268
14269
|
/**
|
|
14269
14270
|
* Closes all watchers for a path
|
|
14270
14271
|
*/
|
|
14271
|
-
_closePath(
|
|
14272
|
-
this._closeFile(
|
|
14273
|
-
const dir = sysPath2.dirname(
|
|
14274
|
-
this._getWatchedDir(dir).remove(sysPath2.basename(
|
|
14272
|
+
_closePath(path36) {
|
|
14273
|
+
this._closeFile(path36);
|
|
14274
|
+
const dir = sysPath2.dirname(path36);
|
|
14275
|
+
this._getWatchedDir(dir).remove(sysPath2.basename(path36));
|
|
14275
14276
|
}
|
|
14276
14277
|
/**
|
|
14277
14278
|
* Closes only file-specific watchers
|
|
14278
14279
|
*/
|
|
14279
|
-
_closeFile(
|
|
14280
|
-
const closers = this._closers.get(
|
|
14280
|
+
_closeFile(path36) {
|
|
14281
|
+
const closers = this._closers.get(path36);
|
|
14281
14282
|
if (!closers)
|
|
14282
14283
|
return;
|
|
14283
14284
|
closers.forEach((closer) => closer());
|
|
14284
|
-
this._closers.delete(
|
|
14285
|
+
this._closers.delete(path36);
|
|
14285
14286
|
}
|
|
14286
|
-
_addPathCloser(
|
|
14287
|
+
_addPathCloser(path36, closer) {
|
|
14287
14288
|
if (!closer)
|
|
14288
14289
|
return;
|
|
14289
|
-
let list = this._closers.get(
|
|
14290
|
+
let list = this._closers.get(path36);
|
|
14290
14291
|
if (!list) {
|
|
14291
14292
|
list = [];
|
|
14292
|
-
this._closers.set(
|
|
14293
|
+
this._closers.set(path36, list);
|
|
14293
14294
|
}
|
|
14294
14295
|
list.push(closer);
|
|
14295
14296
|
}
|
|
@@ -14505,7 +14506,20 @@ var DEFAULT_CONFIG = {
|
|
|
14505
14506
|
ssr: true,
|
|
14506
14507
|
ssg: true
|
|
14507
14508
|
},
|
|
14508
|
-
plugins: []
|
|
14509
|
+
plugins: [],
|
|
14510
|
+
images: {
|
|
14511
|
+
remotePatterns: [],
|
|
14512
|
+
domains: [],
|
|
14513
|
+
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
|
|
14514
|
+
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
|
|
14515
|
+
formats: ["image/webp", "image/avif"],
|
|
14516
|
+
quality: 75,
|
|
14517
|
+
minimumCacheTTL: 60,
|
|
14518
|
+
dangerouslyAllowSVG: false,
|
|
14519
|
+
contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
|
|
14520
|
+
maxWidth: 3840,
|
|
14521
|
+
maxHeight: 3840
|
|
14522
|
+
}
|
|
14509
14523
|
};
|
|
14510
14524
|
function deepMerge(target, source) {
|
|
14511
14525
|
const result = { ...target };
|
|
@@ -14622,6 +14636,53 @@ function validateConfig(config, projectRoot) {
|
|
|
14622
14636
|
if (typeof config.rendering.ssg !== "boolean") {
|
|
14623
14637
|
errors.push("config.rendering.ssg must be a boolean");
|
|
14624
14638
|
}
|
|
14639
|
+
if (config.images) {
|
|
14640
|
+
if (config.images.quality !== void 0) {
|
|
14641
|
+
if (typeof config.images.quality !== "number" || config.images.quality < 1 || config.images.quality > 100) {
|
|
14642
|
+
errors.push("config.images.quality must be a number between 1 and 100");
|
|
14643
|
+
}
|
|
14644
|
+
}
|
|
14645
|
+
if (config.images.minimumCacheTTL !== void 0) {
|
|
14646
|
+
if (typeof config.images.minimumCacheTTL !== "number" || config.images.minimumCacheTTL < 0) {
|
|
14647
|
+
errors.push("config.images.minimumCacheTTL must be a non-negative number");
|
|
14648
|
+
}
|
|
14649
|
+
}
|
|
14650
|
+
if (config.images.deviceSizes) {
|
|
14651
|
+
if (!Array.isArray(config.images.deviceSizes) || config.images.deviceSizes.some((s) => typeof s !== "number" || s <= 0)) {
|
|
14652
|
+
errors.push("config.images.deviceSizes must be an array of positive numbers");
|
|
14653
|
+
}
|
|
14654
|
+
}
|
|
14655
|
+
if (config.images.imageSizes) {
|
|
14656
|
+
if (!Array.isArray(config.images.imageSizes) || config.images.imageSizes.some((s) => typeof s !== "number" || s <= 0)) {
|
|
14657
|
+
errors.push("config.images.imageSizes must be an array of positive numbers");
|
|
14658
|
+
}
|
|
14659
|
+
}
|
|
14660
|
+
if (config.images.formats) {
|
|
14661
|
+
const validFormats = ["image/webp", "image/avif"];
|
|
14662
|
+
if (!Array.isArray(config.images.formats) || config.images.formats.some((f) => !validFormats.includes(f))) {
|
|
14663
|
+
errors.push(`config.images.formats must be an array containing only: ${validFormats.join(", ")}`);
|
|
14664
|
+
}
|
|
14665
|
+
}
|
|
14666
|
+
if (config.images.remotePatterns) {
|
|
14667
|
+
if (!Array.isArray(config.images.remotePatterns)) {
|
|
14668
|
+
errors.push("config.images.remotePatterns must be an array");
|
|
14669
|
+
} else {
|
|
14670
|
+
config.images.remotePatterns.forEach((pattern, idx) => {
|
|
14671
|
+
if (!pattern.hostname || typeof pattern.hostname !== "string") {
|
|
14672
|
+
errors.push(`config.images.remotePatterns[${idx}].hostname must be a non-empty string`);
|
|
14673
|
+
}
|
|
14674
|
+
if (pattern.protocol && !["http", "https"].includes(pattern.protocol)) {
|
|
14675
|
+
errors.push(`config.images.remotePatterns[${idx}].protocol must be 'http' or 'https'`);
|
|
14676
|
+
}
|
|
14677
|
+
});
|
|
14678
|
+
}
|
|
14679
|
+
}
|
|
14680
|
+
if (config.images.domains) {
|
|
14681
|
+
if (!Array.isArray(config.images.domains) || config.images.domains.some((d) => typeof d !== "string")) {
|
|
14682
|
+
errors.push("config.images.domains must be an array of strings");
|
|
14683
|
+
}
|
|
14684
|
+
}
|
|
14685
|
+
}
|
|
14625
14686
|
if (errors.length > 0) {
|
|
14626
14687
|
const errorMessage = [
|
|
14627
14688
|
"\u274C Configuration validation failed:",
|
|
@@ -14967,12 +15028,12 @@ var DEFAULT_IGNORED_PATHS = [
|
|
|
14967
15028
|
/^\/sockjs-node/
|
|
14968
15029
|
// Hot reload websocket
|
|
14969
15030
|
];
|
|
14970
|
-
function shouldIgnorePath(
|
|
15031
|
+
function shouldIgnorePath(path36, ignoredPaths) {
|
|
14971
15032
|
return ignoredPaths.some((pattern) => {
|
|
14972
15033
|
if (typeof pattern === "string") {
|
|
14973
|
-
return
|
|
15034
|
+
return path36 === pattern || path36.startsWith(pattern);
|
|
14974
15035
|
}
|
|
14975
|
-
return pattern.test(
|
|
15036
|
+
return pattern.test(path36);
|
|
14976
15037
|
});
|
|
14977
15038
|
}
|
|
14978
15039
|
function requestLoggerMiddleware(options = {}) {
|
|
@@ -15131,11 +15192,11 @@ function createStrictRateLimiterFromConfig(config) {
|
|
|
15131
15192
|
}
|
|
15132
15193
|
|
|
15133
15194
|
// modules/server/middleware/auto-rate-limit.ts
|
|
15134
|
-
function matchesStrictPattern(
|
|
15195
|
+
function matchesStrictPattern(path36, patterns) {
|
|
15135
15196
|
for (const pattern of patterns) {
|
|
15136
15197
|
const regexPattern = pattern.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*").replace(/\//g, "\\/");
|
|
15137
15198
|
const regex = new RegExp(`^${regexPattern}$`);
|
|
15138
|
-
if (regex.test(
|
|
15199
|
+
if (regex.test(path36)) {
|
|
15139
15200
|
return true;
|
|
15140
15201
|
}
|
|
15141
15202
|
}
|
|
@@ -15658,7 +15719,7 @@ function createDocumentTree(options) {
|
|
|
15658
15719
|
}),
|
|
15659
15720
|
...extraMetaTags,
|
|
15660
15721
|
...linkTags,
|
|
15661
|
-
...entrypointFiles.length > 0 ? entrypointFiles.
|
|
15722
|
+
...entrypointFiles.length > 0 ? entrypointFiles.map(
|
|
15662
15723
|
(file) => React.createElement("link", {
|
|
15663
15724
|
key: `preload-${file}`,
|
|
15664
15725
|
rel: "preload",
|
|
@@ -15679,6 +15740,13 @@ function createDocumentTree(options) {
|
|
|
15679
15740
|
href: faviconPath,
|
|
15680
15741
|
type: faviconType || (faviconPath.endsWith(".ico") ? "image/x-icon" : "image/png")
|
|
15681
15742
|
}),
|
|
15743
|
+
// Preload CSS para evitar bloqueo de renderizado
|
|
15744
|
+
React.createElement("link", {
|
|
15745
|
+
key: "preload-css",
|
|
15746
|
+
rel: "preload",
|
|
15747
|
+
href: clientCssPath,
|
|
15748
|
+
as: "style"
|
|
15749
|
+
}),
|
|
15682
15750
|
React.createElement("link", {
|
|
15683
15751
|
rel: "stylesheet",
|
|
15684
15752
|
href: clientCssPath
|
|
@@ -16825,6 +16893,438 @@ async function renderErrorPageWithStream(errorPage, req, res, error, routeChunks
|
|
|
16825
16893
|
}
|
|
16826
16894
|
}
|
|
16827
16895
|
|
|
16896
|
+
// modules/server/image-optimizer/index.ts
|
|
16897
|
+
import sharp from "sharp";
|
|
16898
|
+
import fs22 from "fs";
|
|
16899
|
+
import path28 from "path";
|
|
16900
|
+
|
|
16901
|
+
// modules/server/image-optimizer/validation.ts
|
|
16902
|
+
import path26 from "path";
|
|
16903
|
+
function isRemoteUrl(url) {
|
|
16904
|
+
return url.startsWith("http://") || url.startsWith("https://");
|
|
16905
|
+
}
|
|
16906
|
+
function sanitizeImagePath(imagePath) {
|
|
16907
|
+
const normalized = path26.normalize(imagePath).replace(/^(\.\.(\/|\\|$))+/, "");
|
|
16908
|
+
return normalized.replace(/^[/\\]+/, "");
|
|
16909
|
+
}
|
|
16910
|
+
function patternToRegex(pattern) {
|
|
16911
|
+
const parts = [];
|
|
16912
|
+
if (pattern.protocol) {
|
|
16913
|
+
parts.push(pattern.protocol === "https" ? "https" : "http");
|
|
16914
|
+
} else {
|
|
16915
|
+
parts.push("https?");
|
|
16916
|
+
}
|
|
16917
|
+
parts.push("://");
|
|
16918
|
+
let hostnamePattern = pattern.hostname.replace(/\./g, "\\.").replace(/\*\*/g, ".*").replace(/\*/g, "[^.]*");
|
|
16919
|
+
parts.push(hostnamePattern);
|
|
16920
|
+
if (pattern.port) {
|
|
16921
|
+
parts.push(`:${pattern.port}`);
|
|
16922
|
+
}
|
|
16923
|
+
if (pattern.pathname) {
|
|
16924
|
+
let pathnamePattern = pattern.pathname.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*");
|
|
16925
|
+
parts.push(pathnamePattern);
|
|
16926
|
+
} else {
|
|
16927
|
+
parts.push(".*");
|
|
16928
|
+
}
|
|
16929
|
+
const regexSource = `^${parts.join("")}`;
|
|
16930
|
+
return new RegExp(regexSource);
|
|
16931
|
+
}
|
|
16932
|
+
function validateRemoteUrl(url, config) {
|
|
16933
|
+
if (!config.remotePatterns && !config.domains) {
|
|
16934
|
+
return false;
|
|
16935
|
+
}
|
|
16936
|
+
try {
|
|
16937
|
+
const urlObj = new URL(url);
|
|
16938
|
+
const protocol = urlObj.protocol.replace(":", "");
|
|
16939
|
+
const hostname = urlObj.hostname;
|
|
16940
|
+
const port = urlObj.port || "";
|
|
16941
|
+
const pathname = urlObj.pathname;
|
|
16942
|
+
if (config.remotePatterns && config.remotePatterns.length > 0) {
|
|
16943
|
+
for (const pattern of config.remotePatterns) {
|
|
16944
|
+
const regex = patternToRegex(pattern);
|
|
16945
|
+
const testUrl = `${protocol}://${hostname}${port ? `:${port}` : ""}${pathname}`;
|
|
16946
|
+
if (regex.test(testUrl)) {
|
|
16947
|
+
if (pattern.protocol && pattern.protocol !== protocol) {
|
|
16948
|
+
continue;
|
|
16949
|
+
}
|
|
16950
|
+
if (pattern.port && pattern.port !== port) {
|
|
16951
|
+
continue;
|
|
16952
|
+
}
|
|
16953
|
+
return true;
|
|
16954
|
+
}
|
|
16955
|
+
}
|
|
16956
|
+
}
|
|
16957
|
+
if (config.domains && config.domains.length > 0) {
|
|
16958
|
+
for (const domain of config.domains) {
|
|
16959
|
+
const domainPattern = domain.replace(/\./g, "\\.").replace(/\*\*/g, ".*").replace(/\*/g, "[^.]*");
|
|
16960
|
+
const regex = new RegExp(`^${domainPattern}$`);
|
|
16961
|
+
if (regex.test(hostname)) {
|
|
16962
|
+
if (process.env.NODE_ENV === "production" && protocol !== "https") {
|
|
16963
|
+
continue;
|
|
16964
|
+
}
|
|
16965
|
+
return true;
|
|
16966
|
+
}
|
|
16967
|
+
}
|
|
16968
|
+
}
|
|
16969
|
+
return false;
|
|
16970
|
+
} catch (error) {
|
|
16971
|
+
return false;
|
|
16972
|
+
}
|
|
16973
|
+
}
|
|
16974
|
+
function validateImageDimensions(width, height, config) {
|
|
16975
|
+
const maxWidth = config.maxWidth || 3840;
|
|
16976
|
+
const maxHeight = config.maxHeight || 3840;
|
|
16977
|
+
if (width !== void 0 && (width <= 0 || width > maxWidth)) {
|
|
16978
|
+
return {
|
|
16979
|
+
valid: false,
|
|
16980
|
+
error: `Image width must be between 1 and ${maxWidth}, got ${width}`
|
|
16981
|
+
};
|
|
16982
|
+
}
|
|
16983
|
+
if (height !== void 0 && (height <= 0 || height > maxHeight)) {
|
|
16984
|
+
return {
|
|
16985
|
+
valid: false,
|
|
16986
|
+
error: `Image height must be between 1 and ${maxHeight}, got ${height}`
|
|
16987
|
+
};
|
|
16988
|
+
}
|
|
16989
|
+
return { valid: true };
|
|
16990
|
+
}
|
|
16991
|
+
function validateQuality(quality) {
|
|
16992
|
+
if (quality === void 0) {
|
|
16993
|
+
return { valid: true };
|
|
16994
|
+
}
|
|
16995
|
+
if (typeof quality !== "number" || quality < 1 || quality > 100) {
|
|
16996
|
+
return {
|
|
16997
|
+
valid: false,
|
|
16998
|
+
error: `Image quality must be between 1 and 100, got ${quality}`
|
|
16999
|
+
};
|
|
17000
|
+
}
|
|
17001
|
+
return { valid: true };
|
|
17002
|
+
}
|
|
17003
|
+
|
|
17004
|
+
// modules/server/image-optimizer/cache.ts
|
|
17005
|
+
import fs21 from "fs";
|
|
17006
|
+
import path27 from "path";
|
|
17007
|
+
import crypto from "crypto";
|
|
17008
|
+
function generateCacheKey(src, width, height, quality, format) {
|
|
17009
|
+
const data = `${src}-${width || ""}-${height || ""}-${quality || ""}-${format || ""}`;
|
|
17010
|
+
return crypto.createHash("sha256").update(data).digest("hex");
|
|
17011
|
+
}
|
|
17012
|
+
function getCacheDir(projectRoot, config) {
|
|
17013
|
+
const buildDir = getBuildDir(projectRoot, config);
|
|
17014
|
+
return path27.join(buildDir, "cache", "images");
|
|
17015
|
+
}
|
|
17016
|
+
function ensureCacheDir(cacheDir) {
|
|
17017
|
+
if (!fs21.existsSync(cacheDir)) {
|
|
17018
|
+
fs21.mkdirSync(cacheDir, { recursive: true });
|
|
17019
|
+
}
|
|
17020
|
+
}
|
|
17021
|
+
function getCachedImagePath(cacheKey, extension, cacheDir) {
|
|
17022
|
+
return path27.join(cacheDir, `${cacheKey}.${extension}`);
|
|
17023
|
+
}
|
|
17024
|
+
function hasCachedImage(cacheKey, extension, cacheDir) {
|
|
17025
|
+
const cachedPath = getCachedImagePath(cacheKey, extension, cacheDir);
|
|
17026
|
+
return fs21.existsSync(cachedPath);
|
|
17027
|
+
}
|
|
17028
|
+
function readCachedImage(cacheKey, extension, cacheDir) {
|
|
17029
|
+
const cachedPath = getCachedImagePath(cacheKey, extension, cacheDir);
|
|
17030
|
+
try {
|
|
17031
|
+
if (fs21.existsSync(cachedPath)) {
|
|
17032
|
+
return fs21.readFileSync(cachedPath);
|
|
17033
|
+
}
|
|
17034
|
+
} catch (error) {
|
|
17035
|
+
console.warn(`[image-optimizer] Failed to read cached image: ${cachedPath}`, error);
|
|
17036
|
+
}
|
|
17037
|
+
return null;
|
|
17038
|
+
}
|
|
17039
|
+
function writeCachedImage(cacheKey, extension, cacheDir, imageBuffer) {
|
|
17040
|
+
ensureCacheDir(cacheDir);
|
|
17041
|
+
const cachedPath = getCachedImagePath(cacheKey, extension, cacheDir);
|
|
17042
|
+
try {
|
|
17043
|
+
fs21.writeFileSync(cachedPath, imageBuffer);
|
|
17044
|
+
} catch (error) {
|
|
17045
|
+
console.warn(`[image-optimizer] Failed to write cached image: ${cachedPath}`, error);
|
|
17046
|
+
}
|
|
17047
|
+
}
|
|
17048
|
+
function getImageMimeType(format) {
|
|
17049
|
+
const formatMap = {
|
|
17050
|
+
webp: "image/webp",
|
|
17051
|
+
avif: "image/avif",
|
|
17052
|
+
jpeg: "image/jpeg",
|
|
17053
|
+
jpg: "image/jpeg",
|
|
17054
|
+
png: "image/png",
|
|
17055
|
+
gif: "image/gif",
|
|
17056
|
+
svg: "image/svg+xml"
|
|
17057
|
+
};
|
|
17058
|
+
const normalized = format.toLowerCase();
|
|
17059
|
+
return formatMap[normalized] || "image/jpeg";
|
|
17060
|
+
}
|
|
17061
|
+
function getImageExtension(format) {
|
|
17062
|
+
const formatMap = {
|
|
17063
|
+
"image/webp": "webp",
|
|
17064
|
+
"image/avif": "avif",
|
|
17065
|
+
"image/jpeg": "jpg",
|
|
17066
|
+
"image/png": "png",
|
|
17067
|
+
"image/gif": "gif",
|
|
17068
|
+
"image/svg+xml": "svg",
|
|
17069
|
+
webp: "webp",
|
|
17070
|
+
avif: "avif",
|
|
17071
|
+
jpeg: "jpg",
|
|
17072
|
+
jpg: "jpg",
|
|
17073
|
+
png: "png",
|
|
17074
|
+
gif: "gif",
|
|
17075
|
+
svg: "svg"
|
|
17076
|
+
};
|
|
17077
|
+
const normalized = format.toLowerCase();
|
|
17078
|
+
return formatMap[normalized] || "jpg";
|
|
17079
|
+
}
|
|
17080
|
+
|
|
17081
|
+
// modules/server/image-optimizer/index.ts
|
|
17082
|
+
async function downloadRemoteImage(url, timeout = 1e4) {
|
|
17083
|
+
let fetchFn;
|
|
17084
|
+
try {
|
|
17085
|
+
if (typeof fetch !== "undefined") {
|
|
17086
|
+
fetchFn = fetch;
|
|
17087
|
+
} else {
|
|
17088
|
+
const { fetch: undiciFetch } = await import("undici");
|
|
17089
|
+
fetchFn = undiciFetch;
|
|
17090
|
+
}
|
|
17091
|
+
} catch (error) {
|
|
17092
|
+
throw new Error("Failed to load fetch implementation. Node 18+ required or install undici.");
|
|
17093
|
+
}
|
|
17094
|
+
const controller = new AbortController();
|
|
17095
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
17096
|
+
try {
|
|
17097
|
+
const response = await fetchFn(url, {
|
|
17098
|
+
signal: controller.signal,
|
|
17099
|
+
headers: {
|
|
17100
|
+
"User-Agent": "Loly-Image-Optimizer/1.0"
|
|
17101
|
+
}
|
|
17102
|
+
});
|
|
17103
|
+
clearTimeout(timeoutId);
|
|
17104
|
+
if (!response.ok) {
|
|
17105
|
+
throw new Error(`Failed to download image: ${response.status} ${response.statusText}`);
|
|
17106
|
+
}
|
|
17107
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
17108
|
+
return Buffer.from(arrayBuffer);
|
|
17109
|
+
} catch (error) {
|
|
17110
|
+
clearTimeout(timeoutId);
|
|
17111
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
17112
|
+
throw new Error(`Image download timeout after ${timeout}ms`);
|
|
17113
|
+
}
|
|
17114
|
+
throw error;
|
|
17115
|
+
}
|
|
17116
|
+
}
|
|
17117
|
+
function readLocalImage(src, projectRoot, config) {
|
|
17118
|
+
const sanitized = sanitizeImagePath(src);
|
|
17119
|
+
const staticDir = getStaticDir(projectRoot, config);
|
|
17120
|
+
const staticPath = path28.join(staticDir, sanitized);
|
|
17121
|
+
if (fs22.existsSync(staticPath)) {
|
|
17122
|
+
return fs22.readFileSync(staticPath);
|
|
17123
|
+
}
|
|
17124
|
+
if (src.startsWith("/")) {
|
|
17125
|
+
const absolutePath = path28.join(projectRoot, sanitized);
|
|
17126
|
+
if (fs22.existsSync(absolutePath)) {
|
|
17127
|
+
return fs22.readFileSync(absolutePath);
|
|
17128
|
+
}
|
|
17129
|
+
}
|
|
17130
|
+
throw new Error(`Image not found: ${src}`);
|
|
17131
|
+
}
|
|
17132
|
+
function determineOutputFormat(sourceFormat, requestedFormat, config) {
|
|
17133
|
+
if (sourceFormat === "svg") {
|
|
17134
|
+
return "svg";
|
|
17135
|
+
}
|
|
17136
|
+
if (requestedFormat && requestedFormat !== "auto") {
|
|
17137
|
+
return requestedFormat;
|
|
17138
|
+
}
|
|
17139
|
+
const supportedFormats = config.formats || ["image/webp"];
|
|
17140
|
+
if (supportedFormats.includes("image/avif")) {
|
|
17141
|
+
return "avif";
|
|
17142
|
+
}
|
|
17143
|
+
if (supportedFormats.includes("image/webp")) {
|
|
17144
|
+
return "webp";
|
|
17145
|
+
}
|
|
17146
|
+
return sourceFormat === "svg" ? "jpeg" : sourceFormat;
|
|
17147
|
+
}
|
|
17148
|
+
async function optimizeImage(options, projectRoot, config) {
|
|
17149
|
+
const imageConfig = config.images || {};
|
|
17150
|
+
const dimValidation = validateImageDimensions(options.width, options.height, imageConfig);
|
|
17151
|
+
if (!dimValidation.valid) {
|
|
17152
|
+
throw new Error(dimValidation.error);
|
|
17153
|
+
}
|
|
17154
|
+
const qualityValidation = validateQuality(options.quality);
|
|
17155
|
+
if (!qualityValidation.valid) {
|
|
17156
|
+
throw new Error(qualityValidation.error);
|
|
17157
|
+
}
|
|
17158
|
+
if (isRemoteUrl(options.src)) {
|
|
17159
|
+
if (!validateRemoteUrl(options.src, imageConfig)) {
|
|
17160
|
+
throw new Error(`Remote image domain not allowed: ${options.src}`);
|
|
17161
|
+
}
|
|
17162
|
+
}
|
|
17163
|
+
const sourceFormat = path28.extname(options.src).slice(1).toLowerCase() || "jpeg";
|
|
17164
|
+
const outputFormat = determineOutputFormat(
|
|
17165
|
+
sourceFormat,
|
|
17166
|
+
options.format,
|
|
17167
|
+
imageConfig
|
|
17168
|
+
);
|
|
17169
|
+
const cacheKey = generateCacheKey(
|
|
17170
|
+
options.src,
|
|
17171
|
+
options.width,
|
|
17172
|
+
options.height,
|
|
17173
|
+
options.quality || imageConfig.quality || 75,
|
|
17174
|
+
outputFormat
|
|
17175
|
+
);
|
|
17176
|
+
const cacheDir = getCacheDir(projectRoot, config);
|
|
17177
|
+
const extension = getImageExtension(outputFormat);
|
|
17178
|
+
if (hasCachedImage(cacheKey, extension, cacheDir)) {
|
|
17179
|
+
const cached = readCachedImage(cacheKey, extension, cacheDir);
|
|
17180
|
+
if (cached) {
|
|
17181
|
+
const metadata2 = await sharp(cached).metadata();
|
|
17182
|
+
return {
|
|
17183
|
+
buffer: cached,
|
|
17184
|
+
format: outputFormat,
|
|
17185
|
+
mimeType: getImageMimeType(outputFormat),
|
|
17186
|
+
width: metadata2.width || options.width || 0,
|
|
17187
|
+
height: metadata2.height || options.height || 0
|
|
17188
|
+
};
|
|
17189
|
+
}
|
|
17190
|
+
}
|
|
17191
|
+
let imageBuffer;
|
|
17192
|
+
if (isRemoteUrl(options.src)) {
|
|
17193
|
+
imageBuffer = await downloadRemoteImage(options.src);
|
|
17194
|
+
} else {
|
|
17195
|
+
imageBuffer = readLocalImage(options.src, projectRoot, config);
|
|
17196
|
+
}
|
|
17197
|
+
if (outputFormat === "svg" || sourceFormat === "svg") {
|
|
17198
|
+
if (!imageConfig.dangerouslyAllowSVG) {
|
|
17199
|
+
throw new Error("SVG images are not allowed. Set images.dangerouslyAllowSVG to true to enable.");
|
|
17200
|
+
}
|
|
17201
|
+
return {
|
|
17202
|
+
buffer: imageBuffer,
|
|
17203
|
+
format: "svg",
|
|
17204
|
+
mimeType: "image/svg+xml",
|
|
17205
|
+
width: options.width || 0,
|
|
17206
|
+
height: options.height || 0
|
|
17207
|
+
};
|
|
17208
|
+
}
|
|
17209
|
+
let sharpInstance = sharp(imageBuffer);
|
|
17210
|
+
const metadata = await sharpInstance.metadata();
|
|
17211
|
+
if (options.width || options.height) {
|
|
17212
|
+
const fit = options.fit || "cover";
|
|
17213
|
+
sharpInstance = sharpInstance.resize(options.width, options.height, {
|
|
17214
|
+
fit,
|
|
17215
|
+
withoutEnlargement: true
|
|
17216
|
+
});
|
|
17217
|
+
}
|
|
17218
|
+
const quality = options.quality || imageConfig.quality || 75;
|
|
17219
|
+
switch (outputFormat) {
|
|
17220
|
+
case "webp":
|
|
17221
|
+
sharpInstance = sharpInstance.webp({ quality });
|
|
17222
|
+
break;
|
|
17223
|
+
case "avif":
|
|
17224
|
+
sharpInstance = sharpInstance.avif({ quality });
|
|
17225
|
+
break;
|
|
17226
|
+
case "jpeg":
|
|
17227
|
+
case "jpg":
|
|
17228
|
+
sharpInstance = sharpInstance.jpeg({ quality });
|
|
17229
|
+
break;
|
|
17230
|
+
case "png":
|
|
17231
|
+
sharpInstance = sharpInstance.png({ quality: Math.round(quality / 100 * 9) });
|
|
17232
|
+
break;
|
|
17233
|
+
default:
|
|
17234
|
+
sharpInstance = sharpInstance.jpeg({ quality });
|
|
17235
|
+
}
|
|
17236
|
+
const optimizedBuffer = await sharpInstance.toBuffer();
|
|
17237
|
+
const finalMetadata = await sharp(optimizedBuffer).metadata();
|
|
17238
|
+
writeCachedImage(cacheKey, extension, cacheDir, optimizedBuffer);
|
|
17239
|
+
return {
|
|
17240
|
+
buffer: optimizedBuffer,
|
|
17241
|
+
format: outputFormat,
|
|
17242
|
+
mimeType: getImageMimeType(outputFormat),
|
|
17243
|
+
width: finalMetadata.width || options.width || metadata.width || 0,
|
|
17244
|
+
height: finalMetadata.height || options.height || metadata.height || 0
|
|
17245
|
+
};
|
|
17246
|
+
}
|
|
17247
|
+
|
|
17248
|
+
// modules/server/handlers/image.ts
|
|
17249
|
+
async function handleImageRequest(options) {
|
|
17250
|
+
const { req, res, projectRoot, config } = options;
|
|
17251
|
+
try {
|
|
17252
|
+
const src = req.query.src;
|
|
17253
|
+
const width = req.query.w ? parseInt(req.query.w, 10) : void 0;
|
|
17254
|
+
const height = req.query.h ? parseInt(req.query.h, 10) : void 0;
|
|
17255
|
+
const quality = req.query.q ? parseInt(req.query.q, 10) : void 0;
|
|
17256
|
+
const format = req.query.format;
|
|
17257
|
+
const fit = req.query.fit;
|
|
17258
|
+
if (!src) {
|
|
17259
|
+
res.status(400).json({
|
|
17260
|
+
error: "Missing required parameter: src"
|
|
17261
|
+
});
|
|
17262
|
+
return;
|
|
17263
|
+
}
|
|
17264
|
+
if (typeof src !== "string") {
|
|
17265
|
+
res.status(400).json({
|
|
17266
|
+
error: "Parameter 'src' must be a string"
|
|
17267
|
+
});
|
|
17268
|
+
return;
|
|
17269
|
+
}
|
|
17270
|
+
const result = await optimizeImage(
|
|
17271
|
+
{
|
|
17272
|
+
src,
|
|
17273
|
+
width,
|
|
17274
|
+
height,
|
|
17275
|
+
quality,
|
|
17276
|
+
format,
|
|
17277
|
+
fit
|
|
17278
|
+
},
|
|
17279
|
+
projectRoot,
|
|
17280
|
+
config
|
|
17281
|
+
);
|
|
17282
|
+
const imageConfig = config.images || {};
|
|
17283
|
+
const cacheTTL = imageConfig.minimumCacheTTL || 60;
|
|
17284
|
+
res.setHeader("Content-Type", result.mimeType);
|
|
17285
|
+
res.setHeader("Content-Length", result.buffer.length);
|
|
17286
|
+
res.setHeader("Cache-Control", `public, max-age=${cacheTTL}, immutable`);
|
|
17287
|
+
res.setHeader("X-Content-Type-Options", "nosniff");
|
|
17288
|
+
res.send(result.buffer);
|
|
17289
|
+
} catch (error) {
|
|
17290
|
+
if (error instanceof Error) {
|
|
17291
|
+
if (error.message.includes("not allowed")) {
|
|
17292
|
+
res.status(403).json({
|
|
17293
|
+
error: "Forbidden",
|
|
17294
|
+
message: error.message
|
|
17295
|
+
});
|
|
17296
|
+
return;
|
|
17297
|
+
}
|
|
17298
|
+
if (error.message.includes("not found") || error.message.includes("Image not found")) {
|
|
17299
|
+
res.status(404).json({
|
|
17300
|
+
error: "Not Found",
|
|
17301
|
+
message: error.message
|
|
17302
|
+
});
|
|
17303
|
+
return;
|
|
17304
|
+
}
|
|
17305
|
+
if (error.message.includes("must be")) {
|
|
17306
|
+
res.status(400).json({
|
|
17307
|
+
error: "Bad Request",
|
|
17308
|
+
message: error.message
|
|
17309
|
+
});
|
|
17310
|
+
return;
|
|
17311
|
+
}
|
|
17312
|
+
if (error.message.includes("timeout") || error.message.includes("download")) {
|
|
17313
|
+
res.status(504).json({
|
|
17314
|
+
error: "Gateway Timeout",
|
|
17315
|
+
message: error.message
|
|
17316
|
+
});
|
|
17317
|
+
return;
|
|
17318
|
+
}
|
|
17319
|
+
}
|
|
17320
|
+
console.error("[image-optimizer] Error processing image:", error);
|
|
17321
|
+
res.status(500).json({
|
|
17322
|
+
error: "Internal Server Error",
|
|
17323
|
+
message: "Failed to process image"
|
|
17324
|
+
});
|
|
17325
|
+
}
|
|
17326
|
+
}
|
|
17327
|
+
|
|
16828
17328
|
// modules/server/routes.ts
|
|
16829
17329
|
init_globals();
|
|
16830
17330
|
|
|
@@ -16986,7 +17486,7 @@ function validateRealtimeConfig(config) {
|
|
|
16986
17486
|
}
|
|
16987
17487
|
|
|
16988
17488
|
// modules/server/routes.ts
|
|
16989
|
-
import
|
|
17489
|
+
import path29 from "path";
|
|
16990
17490
|
var cachedRewriteLoader = null;
|
|
16991
17491
|
var cachedProjectRoot = null;
|
|
16992
17492
|
var cachedIsDev = null;
|
|
@@ -17014,10 +17514,20 @@ function setupRoutes(options) {
|
|
|
17014
17514
|
} = options;
|
|
17015
17515
|
const routeChunks = routeLoader.loadRouteChunks();
|
|
17016
17516
|
const rewriteLoader = getRewriteLoader(projectRoot, isDev);
|
|
17017
|
-
const ssgOutDir =
|
|
17018
|
-
config ? getBuildDir(projectRoot, config) :
|
|
17517
|
+
const ssgOutDir = path29.join(
|
|
17518
|
+
config ? getBuildDir(projectRoot, config) : path29.join(projectRoot, BUILD_FOLDER_NAME),
|
|
17019
17519
|
"ssg"
|
|
17020
17520
|
);
|
|
17521
|
+
if (config) {
|
|
17522
|
+
app.get("/_loly/image", async (req, res) => {
|
|
17523
|
+
await handleImageRequest({
|
|
17524
|
+
req,
|
|
17525
|
+
res,
|
|
17526
|
+
projectRoot,
|
|
17527
|
+
config
|
|
17528
|
+
});
|
|
17529
|
+
});
|
|
17530
|
+
}
|
|
17021
17531
|
app.all("/api/*", async (req, res) => {
|
|
17022
17532
|
const apiRoutes = isDev && getRoutes ? (await getRoutes()).apiRoutes : initialApiRoutes;
|
|
17023
17533
|
const serverConfig = await getServerConfig(projectRoot);
|
|
@@ -18064,7 +18574,7 @@ import cors from "cors";
|
|
|
18064
18574
|
import helmet from "helmet";
|
|
18065
18575
|
import cookieParser from "cookie-parser";
|
|
18066
18576
|
import compression from "compression";
|
|
18067
|
-
import
|
|
18577
|
+
import crypto2 from "crypto";
|
|
18068
18578
|
var setupApplication = async ({
|
|
18069
18579
|
projectRoot
|
|
18070
18580
|
}) => {
|
|
@@ -18173,7 +18683,7 @@ var setupApplication = async ({
|
|
|
18173
18683
|
if (process.env.NODE_ENV !== "development" && security?.contentSecurityPolicy !== false) {
|
|
18174
18684
|
app.use(
|
|
18175
18685
|
(req, res, next) => {
|
|
18176
|
-
const nonce =
|
|
18686
|
+
const nonce = crypto2.randomBytes(16).toString("base64");
|
|
18177
18687
|
res.locals.nonce = nonce;
|
|
18178
18688
|
next();
|
|
18179
18689
|
}
|
|
@@ -18244,8 +18754,8 @@ var setupApplication = async ({
|
|
|
18244
18754
|
|
|
18245
18755
|
// src/server.ts
|
|
18246
18756
|
import dotenv2 from "dotenv";
|
|
18247
|
-
var envPath =
|
|
18248
|
-
if (
|
|
18757
|
+
var envPath = path30.join(process.cwd(), ".env");
|
|
18758
|
+
if (fs23.existsSync(envPath)) {
|
|
18249
18759
|
dotenv2.config({ path: envPath });
|
|
18250
18760
|
} else {
|
|
18251
18761
|
dotenv2.config();
|
|
@@ -18266,8 +18776,8 @@ async function startServer(options = {}) {
|
|
|
18266
18776
|
}
|
|
18267
18777
|
const port = options.port ?? (process.env.PORT ? parseInt(process.env.PORT, 10) : void 0) ?? config.server.port;
|
|
18268
18778
|
const host = process.env.HOST ?? (!isDev ? "0.0.0.0" : void 0) ?? config.server.host;
|
|
18269
|
-
const appDir = options.appDir ?? (isDev ? getAppDir(projectRoot, config) :
|
|
18270
|
-
if (!isDev && !
|
|
18779
|
+
const appDir = options.appDir ?? (isDev ? getAppDir(projectRoot, config) : path30.join(getBuildDir(projectRoot, config), "server"));
|
|
18780
|
+
if (!isDev && !fs23.existsSync(appDir)) {
|
|
18271
18781
|
logger4.error("Compiled directory not found", void 0, {
|
|
18272
18782
|
buildDir: config.directories.build,
|
|
18273
18783
|
appDir,
|
|
@@ -18338,14 +18848,14 @@ async function startProdServer(options = {}) {
|
|
|
18338
18848
|
}
|
|
18339
18849
|
|
|
18340
18850
|
// modules/build/index.ts
|
|
18341
|
-
import
|
|
18342
|
-
import
|
|
18851
|
+
import path35 from "path";
|
|
18852
|
+
import fs26 from "fs";
|
|
18343
18853
|
|
|
18344
18854
|
// modules/build/ssg/builder.ts
|
|
18345
|
-
import
|
|
18855
|
+
import path33 from "path";
|
|
18346
18856
|
|
|
18347
18857
|
// modules/build/ssg/path.ts
|
|
18348
|
-
import
|
|
18858
|
+
import path31 from "path";
|
|
18349
18859
|
function buildPathFromPattern(pattern, params) {
|
|
18350
18860
|
const segments = pattern.split("/").filter(Boolean);
|
|
18351
18861
|
const parts = [];
|
|
@@ -18374,12 +18884,12 @@ function buildPathFromPattern(pattern, params) {
|
|
|
18374
18884
|
}
|
|
18375
18885
|
function pathToOutDir(baseDir, urlPath) {
|
|
18376
18886
|
const clean = urlPath === "/" ? "" : urlPath.replace(/^\/+/, "");
|
|
18377
|
-
return
|
|
18887
|
+
return path31.join(baseDir, clean);
|
|
18378
18888
|
}
|
|
18379
18889
|
|
|
18380
18890
|
// modules/build/ssg/renderer.ts
|
|
18381
|
-
import
|
|
18382
|
-
import
|
|
18891
|
+
import fs24 from "fs";
|
|
18892
|
+
import path32 from "path";
|
|
18383
18893
|
import { renderToString } from "react-dom/server";
|
|
18384
18894
|
init_globals();
|
|
18385
18895
|
async function renderStaticRoute(projectRoot, ssgOutDir, route, urlPath, params, config) {
|
|
@@ -18515,16 +19025,16 @@ async function renderStaticRoute(projectRoot, ssgOutDir, route, urlPath, params,
|
|
|
18515
19025
|
const html = "<!DOCTYPE html>" + renderToString(documentTree);
|
|
18516
19026
|
const dir = pathToOutDir(ssgOutDir, urlPath);
|
|
18517
19027
|
ensureDir(dir);
|
|
18518
|
-
const htmlFile =
|
|
18519
|
-
const dataFile =
|
|
18520
|
-
|
|
18521
|
-
|
|
19028
|
+
const htmlFile = path32.join(dir, "index.html");
|
|
19029
|
+
const dataFile = path32.join(dir, "data.json");
|
|
19030
|
+
fs24.writeFileSync(htmlFile, html, "utf-8");
|
|
19031
|
+
fs24.writeFileSync(dataFile, JSON.stringify(initialData, null, 2), "utf-8");
|
|
18522
19032
|
}
|
|
18523
19033
|
|
|
18524
19034
|
// modules/build/ssg/builder.ts
|
|
18525
19035
|
init_globals();
|
|
18526
19036
|
async function buildStaticPages(projectRoot, routes, config) {
|
|
18527
|
-
const ssgOutDir =
|
|
19037
|
+
const ssgOutDir = path33.join(projectRoot, BUILD_FOLDER_NAME, "ssg");
|
|
18528
19038
|
ensureDir(ssgOutDir);
|
|
18529
19039
|
for (const route of routes) {
|
|
18530
19040
|
if (route.dynamic !== "force-static") continue;
|
|
@@ -18579,36 +19089,36 @@ async function buildStaticPages(projectRoot, routes, config) {
|
|
|
18579
19089
|
}
|
|
18580
19090
|
|
|
18581
19091
|
// modules/build/bundler/server.ts
|
|
18582
|
-
import
|
|
18583
|
-
import
|
|
19092
|
+
import path34 from "path";
|
|
19093
|
+
import fs25 from "fs";
|
|
18584
19094
|
import esbuild from "esbuild";
|
|
18585
19095
|
init_globals();
|
|
18586
19096
|
var SERVER_FILES = [INIT_FILE_NAME, CONFIG_FILE_NAME];
|
|
18587
19097
|
function createPathAliasPlugin(projectRoot, outDir) {
|
|
18588
19098
|
const aliases = loadAliasesFromTsconfig(projectRoot);
|
|
18589
|
-
const tsconfigPath =
|
|
19099
|
+
const tsconfigPath = path34.join(projectRoot, "tsconfig.json");
|
|
18590
19100
|
let baseUrl = ".";
|
|
18591
|
-
if (
|
|
19101
|
+
if (fs25.existsSync(tsconfigPath)) {
|
|
18592
19102
|
try {
|
|
18593
|
-
const tsconfig = JSON.parse(
|
|
19103
|
+
const tsconfig = JSON.parse(fs25.readFileSync(tsconfigPath, "utf-8"));
|
|
18594
19104
|
baseUrl = tsconfig.compilerOptions?.baseUrl ?? ".";
|
|
18595
19105
|
} catch {
|
|
18596
19106
|
}
|
|
18597
19107
|
}
|
|
18598
19108
|
function resolveAliasToRelative(importPath, sourceFile) {
|
|
18599
|
-
if (importPath.startsWith(".") || importPath.startsWith("/") ||
|
|
19109
|
+
if (importPath.startsWith(".") || importPath.startsWith("/") || path34.isAbsolute(importPath) || importPath.includes("node_modules")) {
|
|
18600
19110
|
return null;
|
|
18601
19111
|
}
|
|
18602
19112
|
for (const [aliasKey, aliasPath] of Object.entries(aliases)) {
|
|
18603
19113
|
if (importPath.startsWith(aliasKey + "/") || importPath === aliasKey) {
|
|
18604
19114
|
const restPath = importPath.startsWith(aliasKey + "/") ? importPath.slice(aliasKey.length + 1) : "";
|
|
18605
|
-
const resolvedPath = restPath ?
|
|
19115
|
+
const resolvedPath = restPath ? path34.join(aliasPath, restPath) : aliasPath;
|
|
18606
19116
|
let actualPath = null;
|
|
18607
19117
|
const extensions = [".ts", ".tsx", ".js", ".jsx", ".json"];
|
|
18608
|
-
if (
|
|
19118
|
+
if (fs25.existsSync(resolvedPath) && fs25.statSync(resolvedPath).isDirectory()) {
|
|
18609
19119
|
for (const ext of extensions) {
|
|
18610
|
-
const indexPath =
|
|
18611
|
-
if (
|
|
19120
|
+
const indexPath = path34.join(resolvedPath, `index${ext}`);
|
|
19121
|
+
if (fs25.existsSync(indexPath)) {
|
|
18612
19122
|
actualPath = indexPath;
|
|
18613
19123
|
break;
|
|
18614
19124
|
}
|
|
@@ -18616,20 +19126,20 @@ function createPathAliasPlugin(projectRoot, outDir) {
|
|
|
18616
19126
|
} else {
|
|
18617
19127
|
for (const ext of extensions) {
|
|
18618
19128
|
const filePath = resolvedPath + ext;
|
|
18619
|
-
if (
|
|
19129
|
+
if (fs25.existsSync(filePath)) {
|
|
18620
19130
|
actualPath = filePath;
|
|
18621
19131
|
break;
|
|
18622
19132
|
}
|
|
18623
19133
|
}
|
|
18624
|
-
if (!actualPath &&
|
|
19134
|
+
if (!actualPath && fs25.existsSync(resolvedPath)) {
|
|
18625
19135
|
actualPath = resolvedPath;
|
|
18626
19136
|
}
|
|
18627
19137
|
}
|
|
18628
19138
|
if (actualPath) {
|
|
18629
|
-
const relativePath =
|
|
19139
|
+
const relativePath = path34.relative(outDir, actualPath);
|
|
18630
19140
|
const normalizedPath = relativePath.replace(/\\/g, "/");
|
|
18631
19141
|
const finalPath = normalizedPath.startsWith(".") ? normalizedPath : `./${normalizedPath}`;
|
|
18632
|
-
const ext =
|
|
19142
|
+
const ext = path34.extname(finalPath);
|
|
18633
19143
|
const pathWithoutExt = ext === ".json" ? finalPath : finalPath.slice(0, -ext.length);
|
|
18634
19144
|
return pathWithoutExt;
|
|
18635
19145
|
}
|
|
@@ -18641,19 +19151,19 @@ function createPathAliasPlugin(projectRoot, outDir) {
|
|
|
18641
19151
|
name: "path-alias-resolver",
|
|
18642
19152
|
setup(build) {
|
|
18643
19153
|
function resolveAliasToAbsolute(importPath) {
|
|
18644
|
-
if (importPath.startsWith(".") || importPath.startsWith("/") ||
|
|
19154
|
+
if (importPath.startsWith(".") || importPath.startsWith("/") || path34.isAbsolute(importPath) || importPath.includes("node_modules")) {
|
|
18645
19155
|
return null;
|
|
18646
19156
|
}
|
|
18647
19157
|
for (const [aliasKey, aliasPath] of Object.entries(aliases)) {
|
|
18648
19158
|
if (importPath.startsWith(aliasKey + "/") || importPath === aliasKey) {
|
|
18649
19159
|
const restPath = importPath.startsWith(aliasKey + "/") ? importPath.slice(aliasKey.length + 1) : "";
|
|
18650
|
-
const resolvedPath = restPath ?
|
|
19160
|
+
const resolvedPath = restPath ? path34.join(aliasPath, restPath) : aliasPath;
|
|
18651
19161
|
let actualPath = null;
|
|
18652
19162
|
const extensions = [".ts", ".tsx", ".js", ".jsx", ".json"];
|
|
18653
|
-
if (
|
|
19163
|
+
if (fs25.existsSync(resolvedPath) && fs25.statSync(resolvedPath).isDirectory()) {
|
|
18654
19164
|
for (const ext of extensions) {
|
|
18655
|
-
const indexPath =
|
|
18656
|
-
if (
|
|
19165
|
+
const indexPath = path34.join(resolvedPath, `index${ext}`);
|
|
19166
|
+
if (fs25.existsSync(indexPath)) {
|
|
18657
19167
|
actualPath = indexPath;
|
|
18658
19168
|
break;
|
|
18659
19169
|
}
|
|
@@ -18661,12 +19171,12 @@ function createPathAliasPlugin(projectRoot, outDir) {
|
|
|
18661
19171
|
} else {
|
|
18662
19172
|
for (const ext of extensions) {
|
|
18663
19173
|
const filePath = resolvedPath + ext;
|
|
18664
|
-
if (
|
|
19174
|
+
if (fs25.existsSync(filePath)) {
|
|
18665
19175
|
actualPath = filePath;
|
|
18666
19176
|
break;
|
|
18667
19177
|
}
|
|
18668
19178
|
}
|
|
18669
|
-
if (!actualPath &&
|
|
19179
|
+
if (!actualPath && fs25.existsSync(resolvedPath)) {
|
|
18670
19180
|
actualPath = resolvedPath;
|
|
18671
19181
|
}
|
|
18672
19182
|
}
|
|
@@ -18679,7 +19189,7 @@ function createPathAliasPlugin(projectRoot, outDir) {
|
|
|
18679
19189
|
}
|
|
18680
19190
|
build.onResolve({ filter: /^[^./]/ }, (args) => {
|
|
18681
19191
|
const absolutePath = resolveAliasToAbsolute(args.path);
|
|
18682
|
-
if (absolutePath &&
|
|
19192
|
+
if (absolutePath && fs25.existsSync(absolutePath)) {
|
|
18683
19193
|
return {
|
|
18684
19194
|
path: absolutePath,
|
|
18685
19195
|
namespace: "file"
|
|
@@ -18688,13 +19198,13 @@ function createPathAliasPlugin(projectRoot, outDir) {
|
|
|
18688
19198
|
return null;
|
|
18689
19199
|
});
|
|
18690
19200
|
build.onLoad({ filter: /\.(ts|tsx|js|jsx)$/ }, (args) => {
|
|
18691
|
-
const fileName =
|
|
19201
|
+
const fileName = path34.basename(args.path);
|
|
18692
19202
|
const isServerFile = SERVER_FILES.some((f) => fileName === `${f}.ts` || fileName === `${f}.tsx` || fileName === `${f}.js` || fileName === `${f}.jsx`);
|
|
18693
|
-
const isInProjectRoot =
|
|
19203
|
+
const isInProjectRoot = path34.dirname(args.path) === projectRoot;
|
|
18694
19204
|
if (!isServerFile || !isInProjectRoot) {
|
|
18695
19205
|
return null;
|
|
18696
19206
|
}
|
|
18697
|
-
const contents =
|
|
19207
|
+
const contents = fs25.readFileSync(args.path, "utf-8");
|
|
18698
19208
|
let transformed = contents;
|
|
18699
19209
|
const aliasPatterns = Object.keys(aliases).sort((a, b) => b.length - a.length);
|
|
18700
19210
|
for (const aliasKey of aliasPatterns) {
|
|
@@ -18714,7 +19224,7 @@ function createPathAliasPlugin(projectRoot, outDir) {
|
|
|
18714
19224
|
}
|
|
18715
19225
|
return {
|
|
18716
19226
|
contents: transformed,
|
|
18717
|
-
loader:
|
|
19227
|
+
loader: path34.extname(args.path).slice(1)
|
|
18718
19228
|
};
|
|
18719
19229
|
});
|
|
18720
19230
|
}
|
|
@@ -18726,13 +19236,13 @@ function rewritePathAliasesInOutput(outDir, projectRoot, appDir) {
|
|
|
18726
19236
|
for (const [aliasKey, aliasSourcePath] of Object.entries(aliases)) {
|
|
18727
19237
|
if (aliasPath.startsWith(aliasKey + "/") || aliasPath === aliasKey) {
|
|
18728
19238
|
const restPath = aliasPath.startsWith(aliasKey + "/") ? aliasPath.slice(aliasKey.length + 1) : "";
|
|
18729
|
-
const resolvedSourcePath = restPath ?
|
|
19239
|
+
const resolvedSourcePath = restPath ? path34.join(aliasSourcePath, restPath) : aliasSourcePath;
|
|
18730
19240
|
let actualSourcePath = null;
|
|
18731
19241
|
const extensions = [".ts", ".tsx", ".js", ".jsx", ".json"];
|
|
18732
|
-
if (
|
|
19242
|
+
if (fs25.existsSync(resolvedSourcePath) && fs25.statSync(resolvedSourcePath).isDirectory()) {
|
|
18733
19243
|
for (const ext of extensions) {
|
|
18734
|
-
const indexPath =
|
|
18735
|
-
if (
|
|
19244
|
+
const indexPath = path34.join(resolvedSourcePath, `index${ext}`);
|
|
19245
|
+
if (fs25.existsSync(indexPath)) {
|
|
18736
19246
|
actualSourcePath = indexPath;
|
|
18737
19247
|
break;
|
|
18738
19248
|
}
|
|
@@ -18740,21 +19250,21 @@ function rewritePathAliasesInOutput(outDir, projectRoot, appDir) {
|
|
|
18740
19250
|
} else {
|
|
18741
19251
|
for (const ext of extensions) {
|
|
18742
19252
|
const filePath = resolvedSourcePath + ext;
|
|
18743
|
-
if (
|
|
19253
|
+
if (fs25.existsSync(filePath)) {
|
|
18744
19254
|
actualSourcePath = filePath;
|
|
18745
19255
|
break;
|
|
18746
19256
|
}
|
|
18747
19257
|
}
|
|
18748
|
-
if (!actualSourcePath &&
|
|
19258
|
+
if (!actualSourcePath && fs25.existsSync(resolvedSourcePath)) {
|
|
18749
19259
|
actualSourcePath = resolvedSourcePath;
|
|
18750
19260
|
}
|
|
18751
19261
|
}
|
|
18752
19262
|
if (actualSourcePath) {
|
|
18753
|
-
const relativeFromApp =
|
|
18754
|
-
const outputPath =
|
|
19263
|
+
const relativeFromApp = path34.relative(appDir, actualSourcePath);
|
|
19264
|
+
const outputPath = path34.join(outDir, relativeFromApp);
|
|
18755
19265
|
const pathWithoutExt = outputPath.replace(/\.(ts|tsx|js|jsx|json)$/, "");
|
|
18756
19266
|
const compiledPath = pathWithoutExt + ".mjs";
|
|
18757
|
-
if (
|
|
19267
|
+
if (fs25.existsSync(compiledPath)) {
|
|
18758
19268
|
return compiledPath;
|
|
18759
19269
|
}
|
|
18760
19270
|
}
|
|
@@ -18763,17 +19273,17 @@ function rewritePathAliasesInOutput(outDir, projectRoot, appDir) {
|
|
|
18763
19273
|
return null;
|
|
18764
19274
|
}
|
|
18765
19275
|
function walkAndRewrite(dir) {
|
|
18766
|
-
if (!
|
|
18767
|
-
const items =
|
|
19276
|
+
if (!fs25.existsSync(dir)) return;
|
|
19277
|
+
const items = fs25.readdirSync(dir, { withFileTypes: true });
|
|
18768
19278
|
for (const item of items) {
|
|
18769
|
-
const full =
|
|
19279
|
+
const full = path34.join(dir, item.name);
|
|
18770
19280
|
if (item.isDirectory()) {
|
|
18771
19281
|
walkAndRewrite(full);
|
|
18772
19282
|
continue;
|
|
18773
19283
|
}
|
|
18774
19284
|
if (item.isFile() && full.endsWith(".mjs")) {
|
|
18775
19285
|
try {
|
|
18776
|
-
let content =
|
|
19286
|
+
let content = fs25.readFileSync(full, "utf-8");
|
|
18777
19287
|
let modified = false;
|
|
18778
19288
|
const aliasPatterns = Object.keys(aliases).sort((a, b) => b.length - a.length);
|
|
18779
19289
|
for (const aliasKey of aliasPatterns) {
|
|
@@ -18785,8 +19295,8 @@ function rewritePathAliasesInOutput(outDir, projectRoot, appDir) {
|
|
|
18785
19295
|
content = content.replace(aliasInQuotesPattern, (match, quote1, rest, quote2) => {
|
|
18786
19296
|
const fullAliasPath = aliasKey + (rest || "");
|
|
18787
19297
|
const resolvedOutputPath = resolveAliasToOutputPath(fullAliasPath);
|
|
18788
|
-
if (resolvedOutputPath &&
|
|
18789
|
-
const relativePath =
|
|
19298
|
+
if (resolvedOutputPath && fs25.existsSync(resolvedOutputPath)) {
|
|
19299
|
+
const relativePath = path34.relative(path34.dirname(full), resolvedOutputPath);
|
|
18790
19300
|
let normalizedPath = relativePath.replace(/\\/g, "/");
|
|
18791
19301
|
if (!normalizedPath.startsWith(".")) {
|
|
18792
19302
|
normalizedPath = `./${normalizedPath}`;
|
|
@@ -18799,7 +19309,7 @@ function rewritePathAliasesInOutput(outDir, projectRoot, appDir) {
|
|
|
18799
19309
|
});
|
|
18800
19310
|
}
|
|
18801
19311
|
if (modified) {
|
|
18802
|
-
|
|
19312
|
+
fs25.writeFileSync(full, content, "utf-8");
|
|
18803
19313
|
}
|
|
18804
19314
|
} catch (error) {
|
|
18805
19315
|
console.warn(`[framework] Warning: Could not rewrite path aliases in ${full}:`, error instanceof Error ? error.message : String(error));
|
|
@@ -18810,14 +19320,14 @@ function rewritePathAliasesInOutput(outDir, projectRoot, appDir) {
|
|
|
18810
19320
|
walkAndRewrite(outDir);
|
|
18811
19321
|
}
|
|
18812
19322
|
function copyStaticFilesFromApp(appDir, outDir) {
|
|
18813
|
-
if (!
|
|
19323
|
+
if (!fs25.existsSync(appDir)) return;
|
|
18814
19324
|
const sourceExtensions = [".ts", ".tsx", ".js", ".jsx", ".d.ts", ".map"];
|
|
18815
19325
|
function walk(srcDir, destDir) {
|
|
18816
|
-
if (!
|
|
18817
|
-
const items =
|
|
19326
|
+
if (!fs25.existsSync(srcDir)) return;
|
|
19327
|
+
const items = fs25.readdirSync(srcDir, { withFileTypes: true });
|
|
18818
19328
|
for (const item of items) {
|
|
18819
|
-
const srcPath =
|
|
18820
|
-
const destPath =
|
|
19329
|
+
const srcPath = path34.join(srcDir, item.name);
|
|
19330
|
+
const destPath = path34.join(destDir, item.name);
|
|
18821
19331
|
if (item.isDirectory()) {
|
|
18822
19332
|
if (item.name === "node_modules" || item.name.startsWith(".")) {
|
|
18823
19333
|
continue;
|
|
@@ -18827,10 +19337,10 @@ function copyStaticFilesFromApp(appDir, outDir) {
|
|
|
18827
19337
|
continue;
|
|
18828
19338
|
}
|
|
18829
19339
|
if (item.isFile()) {
|
|
18830
|
-
const ext =
|
|
19340
|
+
const ext = path34.extname(item.name).toLowerCase();
|
|
18831
19341
|
if (!sourceExtensions.includes(ext)) {
|
|
18832
19342
|
ensureDir(destDir);
|
|
18833
|
-
|
|
19343
|
+
fs25.copyFileSync(srcPath, destPath);
|
|
18834
19344
|
}
|
|
18835
19345
|
}
|
|
18836
19346
|
}
|
|
@@ -18840,9 +19350,9 @@ function copyStaticFilesFromApp(appDir, outDir) {
|
|
|
18840
19350
|
function collectAppSources(appDir) {
|
|
18841
19351
|
const entries = [];
|
|
18842
19352
|
function walk(dir) {
|
|
18843
|
-
const items =
|
|
19353
|
+
const items = fs25.readdirSync(dir, { withFileTypes: true });
|
|
18844
19354
|
for (const item of items) {
|
|
18845
|
-
const full =
|
|
19355
|
+
const full = path34.join(dir, item.name);
|
|
18846
19356
|
if (item.isDirectory()) {
|
|
18847
19357
|
walk(full);
|
|
18848
19358
|
continue;
|
|
@@ -18859,7 +19369,7 @@ function collectAppSources(appDir) {
|
|
|
18859
19369
|
return entries;
|
|
18860
19370
|
}
|
|
18861
19371
|
async function buildServerApp(projectRoot, appDir, config) {
|
|
18862
|
-
const outDir =
|
|
19372
|
+
const outDir = path34.join(projectRoot, BUILD_FOLDER_NAME, "server");
|
|
18863
19373
|
const entryPoints = collectAppSources(appDir);
|
|
18864
19374
|
ensureDir(outDir);
|
|
18865
19375
|
if (entryPoints.length === 0) {
|
|
@@ -18878,7 +19388,7 @@ async function buildServerApp(projectRoot, appDir, config) {
|
|
|
18878
19388
|
bundle: true,
|
|
18879
19389
|
splitting: false,
|
|
18880
19390
|
logLevel: "info",
|
|
18881
|
-
tsconfig:
|
|
19391
|
+
tsconfig: path34.join(projectRoot, "tsconfig.json"),
|
|
18882
19392
|
packages: "external",
|
|
18883
19393
|
outExtension: { ".js": ".mjs" },
|
|
18884
19394
|
plugins: [pathAliasPlugin]
|
|
@@ -18887,9 +19397,9 @@ async function buildServerApp(projectRoot, appDir, config) {
|
|
|
18887
19397
|
copyStaticFilesFromApp(appDir, outDir);
|
|
18888
19398
|
rewritePathAliasesInOutput(outDir, projectRoot, appDir);
|
|
18889
19399
|
for (const fileName of SERVER_FILES) {
|
|
18890
|
-
const initTS =
|
|
18891
|
-
if (
|
|
18892
|
-
const initJSWithExt =
|
|
19400
|
+
const initTS = path34.join(projectRoot, `${fileName}.ts`);
|
|
19401
|
+
if (fs25.existsSync(initTS)) {
|
|
19402
|
+
const initJSWithExt = path34.join(outDir, `${fileName}.mjs`);
|
|
18893
19403
|
await esbuild.build({
|
|
18894
19404
|
entryPoints: [initTS],
|
|
18895
19405
|
outfile: initJSWithExt,
|
|
@@ -18901,7 +19411,7 @@ async function buildServerApp(projectRoot, appDir, config) {
|
|
|
18901
19411
|
bundle: true,
|
|
18902
19412
|
packages: "external",
|
|
18903
19413
|
logLevel: "info",
|
|
18904
|
-
tsconfig:
|
|
19414
|
+
tsconfig: path34.join(projectRoot, "tsconfig.json"),
|
|
18905
19415
|
plugins: [pathAliasPlugin],
|
|
18906
19416
|
outExtension: { ".js": ".mjs" }
|
|
18907
19417
|
});
|
|
@@ -18917,8 +19427,8 @@ async function buildApp(options = {}) {
|
|
|
18917
19427
|
const config = options.config ?? loadConfig(projectRoot);
|
|
18918
19428
|
const appDir = options.appDir ?? getAppDir(projectRoot, config);
|
|
18919
19429
|
try {
|
|
18920
|
-
const tsxPath =
|
|
18921
|
-
if (
|
|
19430
|
+
const tsxPath = path35.join(projectRoot, "node_modules", "tsx", "dist", "esm", "index.mjs");
|
|
19431
|
+
if (fs26.existsSync(tsxPath)) {
|
|
18922
19432
|
const { pathToFileURL: pathToFileURL2 } = await import("url");
|
|
18923
19433
|
const tsxUrl = pathToFileURL2(tsxPath).href;
|
|
18924
19434
|
await import(tsxUrl);
|
|
@@ -19187,132 +19697,134 @@ function getOrCreateLink(rel, href) {
|
|
|
19187
19697
|
}
|
|
19188
19698
|
function applyMetadata(md) {
|
|
19189
19699
|
if (!md) return;
|
|
19190
|
-
|
|
19191
|
-
|
|
19192
|
-
|
|
19193
|
-
|
|
19194
|
-
|
|
19195
|
-
|
|
19196
|
-
|
|
19197
|
-
|
|
19198
|
-
|
|
19199
|
-
|
|
19200
|
-
|
|
19201
|
-
|
|
19202
|
-
|
|
19203
|
-
|
|
19204
|
-
|
|
19205
|
-
|
|
19206
|
-
|
|
19207
|
-
|
|
19208
|
-
|
|
19209
|
-
|
|
19210
|
-
|
|
19211
|
-
|
|
19212
|
-
|
|
19213
|
-
|
|
19214
|
-
|
|
19215
|
-
|
|
19216
|
-
|
|
19217
|
-
|
|
19218
|
-
|
|
19219
|
-
|
|
19220
|
-
|
|
19221
|
-
|
|
19222
|
-
|
|
19223
|
-
|
|
19224
|
-
|
|
19225
|
-
|
|
19226
|
-
|
|
19227
|
-
|
|
19228
|
-
|
|
19229
|
-
|
|
19230
|
-
|
|
19231
|
-
if (
|
|
19232
|
-
|
|
19233
|
-
|
|
19234
|
-
|
|
19235
|
-
|
|
19236
|
-
|
|
19237
|
-
|
|
19238
|
-
|
|
19239
|
-
|
|
19240
|
-
|
|
19241
|
-
|
|
19242
|
-
|
|
19243
|
-
|
|
19244
|
-
|
|
19245
|
-
|
|
19246
|
-
|
|
19247
|
-
|
|
19700
|
+
requestAnimationFrame(() => {
|
|
19701
|
+
if (md.title) {
|
|
19702
|
+
document.title = md.title;
|
|
19703
|
+
}
|
|
19704
|
+
if (md.description) {
|
|
19705
|
+
const meta = getOrCreateMeta('meta[name="description"]', { name: "description" });
|
|
19706
|
+
meta.content = md.description;
|
|
19707
|
+
}
|
|
19708
|
+
if (md.robots) {
|
|
19709
|
+
const meta = getOrCreateMeta('meta[name="robots"]', { name: "robots" });
|
|
19710
|
+
meta.content = md.robots;
|
|
19711
|
+
}
|
|
19712
|
+
if (md.themeColor) {
|
|
19713
|
+
const meta = getOrCreateMeta('meta[name="theme-color"]', { name: "theme-color" });
|
|
19714
|
+
meta.content = md.themeColor;
|
|
19715
|
+
}
|
|
19716
|
+
if (md.viewport) {
|
|
19717
|
+
const meta = getOrCreateMeta('meta[name="viewport"]', { name: "viewport" });
|
|
19718
|
+
meta.content = md.viewport;
|
|
19719
|
+
}
|
|
19720
|
+
if (md.canonical) {
|
|
19721
|
+
getOrCreateLink("canonical", md.canonical);
|
|
19722
|
+
}
|
|
19723
|
+
if (md.openGraph) {
|
|
19724
|
+
const og = md.openGraph;
|
|
19725
|
+
if (og.title) {
|
|
19726
|
+
const meta = getOrCreateMeta('meta[property="og:title"]', { property: "og:title" });
|
|
19727
|
+
meta.content = og.title;
|
|
19728
|
+
}
|
|
19729
|
+
if (og.description) {
|
|
19730
|
+
const meta = getOrCreateMeta('meta[property="og:description"]', { property: "og:description" });
|
|
19731
|
+
meta.content = og.description;
|
|
19732
|
+
}
|
|
19733
|
+
if (og.type) {
|
|
19734
|
+
const meta = getOrCreateMeta('meta[property="og:type"]', { property: "og:type" });
|
|
19735
|
+
meta.content = og.type;
|
|
19736
|
+
}
|
|
19737
|
+
if (og.url) {
|
|
19738
|
+
const meta = getOrCreateMeta('meta[property="og:url"]', { property: "og:url" });
|
|
19739
|
+
meta.content = og.url;
|
|
19740
|
+
}
|
|
19741
|
+
if (og.image) {
|
|
19742
|
+
if (typeof og.image === "string") {
|
|
19743
|
+
const meta = getOrCreateMeta('meta[property="og:image"]', { property: "og:image" });
|
|
19744
|
+
meta.content = og.image;
|
|
19745
|
+
} else {
|
|
19746
|
+
const meta = getOrCreateMeta('meta[property="og:image"]', { property: "og:image" });
|
|
19747
|
+
meta.content = og.image.url;
|
|
19748
|
+
if (og.image.width) {
|
|
19749
|
+
const metaWidth = getOrCreateMeta('meta[property="og:image:width"]', { property: "og:image:width" });
|
|
19750
|
+
metaWidth.content = String(og.image.width);
|
|
19751
|
+
}
|
|
19752
|
+
if (og.image.height) {
|
|
19753
|
+
const metaHeight = getOrCreateMeta('meta[property="og:image:height"]', { property: "og:image:height" });
|
|
19754
|
+
metaHeight.content = String(og.image.height);
|
|
19755
|
+
}
|
|
19756
|
+
if (og.image.alt) {
|
|
19757
|
+
const metaAlt = getOrCreateMeta('meta[property="og:image:alt"]', { property: "og:image:alt" });
|
|
19758
|
+
metaAlt.content = og.image.alt;
|
|
19759
|
+
}
|
|
19248
19760
|
}
|
|
19249
19761
|
}
|
|
19762
|
+
if (og.siteName) {
|
|
19763
|
+
const meta = getOrCreateMeta('meta[property="og:site_name"]', { property: "og:site_name" });
|
|
19764
|
+
meta.content = og.siteName;
|
|
19765
|
+
}
|
|
19766
|
+
if (og.locale) {
|
|
19767
|
+
const meta = getOrCreateMeta('meta[property="og:locale"]', { property: "og:locale" });
|
|
19768
|
+
meta.content = og.locale;
|
|
19769
|
+
}
|
|
19250
19770
|
}
|
|
19251
|
-
if (
|
|
19252
|
-
const
|
|
19253
|
-
|
|
19254
|
-
|
|
19255
|
-
|
|
19256
|
-
|
|
19257
|
-
|
|
19258
|
-
|
|
19259
|
-
|
|
19260
|
-
|
|
19261
|
-
|
|
19262
|
-
|
|
19263
|
-
|
|
19264
|
-
|
|
19265
|
-
|
|
19266
|
-
|
|
19267
|
-
|
|
19268
|
-
|
|
19269
|
-
|
|
19270
|
-
|
|
19271
|
-
|
|
19272
|
-
|
|
19273
|
-
|
|
19274
|
-
|
|
19275
|
-
|
|
19276
|
-
|
|
19771
|
+
if (md.twitter) {
|
|
19772
|
+
const twitter = md.twitter;
|
|
19773
|
+
if (twitter.card) {
|
|
19774
|
+
const meta = getOrCreateMeta('meta[name="twitter:card"]', { name: "twitter:card" });
|
|
19775
|
+
meta.content = twitter.card;
|
|
19776
|
+
}
|
|
19777
|
+
if (twitter.title) {
|
|
19778
|
+
const meta = getOrCreateMeta('meta[name="twitter:title"]', { name: "twitter:title" });
|
|
19779
|
+
meta.content = twitter.title;
|
|
19780
|
+
}
|
|
19781
|
+
if (twitter.description) {
|
|
19782
|
+
const meta = getOrCreateMeta('meta[name="twitter:description"]', { name: "twitter:description" });
|
|
19783
|
+
meta.content = twitter.description;
|
|
19784
|
+
}
|
|
19785
|
+
if (twitter.image) {
|
|
19786
|
+
const meta = getOrCreateMeta('meta[name="twitter:image"]', { name: "twitter:image" });
|
|
19787
|
+
meta.content = twitter.image;
|
|
19788
|
+
}
|
|
19789
|
+
if (twitter.imageAlt) {
|
|
19790
|
+
const meta = getOrCreateMeta('meta[name="twitter:image:alt"]', { name: "twitter:image:alt" });
|
|
19791
|
+
meta.content = twitter.imageAlt;
|
|
19792
|
+
}
|
|
19793
|
+
if (twitter.site) {
|
|
19794
|
+
const meta = getOrCreateMeta('meta[name="twitter:site"]', { name: "twitter:site" });
|
|
19795
|
+
meta.content = twitter.site;
|
|
19796
|
+
}
|
|
19797
|
+
if (twitter.creator) {
|
|
19798
|
+
const meta = getOrCreateMeta('meta[name="twitter:creator"]', { name: "twitter:creator" });
|
|
19799
|
+
meta.content = twitter.creator;
|
|
19800
|
+
}
|
|
19277
19801
|
}
|
|
19278
|
-
if (
|
|
19279
|
-
|
|
19280
|
-
|
|
19802
|
+
if (md.metaTags && Array.isArray(md.metaTags)) {
|
|
19803
|
+
md.metaTags.forEach((tag) => {
|
|
19804
|
+
let selector = "";
|
|
19805
|
+
if (tag.name) {
|
|
19806
|
+
selector = `meta[name="${tag.name}"]`;
|
|
19807
|
+
} else if (tag.property) {
|
|
19808
|
+
selector = `meta[property="${tag.property}"]`;
|
|
19809
|
+
} else if (tag.httpEquiv) {
|
|
19810
|
+
selector = `meta[http-equiv="${tag.httpEquiv}"]`;
|
|
19811
|
+
}
|
|
19812
|
+
if (selector) {
|
|
19813
|
+
const meta = getOrCreateMeta(selector, {
|
|
19814
|
+
name: tag.name,
|
|
19815
|
+
property: tag.property,
|
|
19816
|
+
httpEquiv: tag.httpEquiv
|
|
19817
|
+
});
|
|
19818
|
+
meta.content = tag.content;
|
|
19819
|
+
}
|
|
19820
|
+
});
|
|
19281
19821
|
}
|
|
19282
|
-
if (
|
|
19283
|
-
|
|
19284
|
-
|
|
19822
|
+
if (md.links && Array.isArray(md.links)) {
|
|
19823
|
+
md.links.forEach((link) => {
|
|
19824
|
+
getOrCreateLink(link.rel, link.href);
|
|
19825
|
+
});
|
|
19285
19826
|
}
|
|
19286
|
-
|
|
19287
|
-
const meta = getOrCreateMeta('meta[name="twitter:creator"]', { name: "twitter:creator" });
|
|
19288
|
-
meta.content = twitter.creator;
|
|
19289
|
-
}
|
|
19290
|
-
}
|
|
19291
|
-
if (md.metaTags && Array.isArray(md.metaTags)) {
|
|
19292
|
-
md.metaTags.forEach((tag) => {
|
|
19293
|
-
let selector = "";
|
|
19294
|
-
if (tag.name) {
|
|
19295
|
-
selector = `meta[name="${tag.name}"]`;
|
|
19296
|
-
} else if (tag.property) {
|
|
19297
|
-
selector = `meta[property="${tag.property}"]`;
|
|
19298
|
-
} else if (tag.httpEquiv) {
|
|
19299
|
-
selector = `meta[http-equiv="${tag.httpEquiv}"]`;
|
|
19300
|
-
}
|
|
19301
|
-
if (selector) {
|
|
19302
|
-
const meta = getOrCreateMeta(selector, {
|
|
19303
|
-
name: tag.name,
|
|
19304
|
-
property: tag.property,
|
|
19305
|
-
httpEquiv: tag.httpEquiv
|
|
19306
|
-
});
|
|
19307
|
-
meta.content = tag.content;
|
|
19308
|
-
}
|
|
19309
|
-
});
|
|
19310
|
-
}
|
|
19311
|
-
if (md.links && Array.isArray(md.links)) {
|
|
19312
|
-
md.links.forEach((link) => {
|
|
19313
|
-
getOrCreateLink(link.rel, link.href);
|
|
19314
|
-
});
|
|
19315
|
-
}
|
|
19827
|
+
});
|
|
19316
19828
|
}
|
|
19317
19829
|
|
|
19318
19830
|
// modules/runtime/client/AppShell.tsx
|
|
@@ -20202,11 +20714,11 @@ var ValidationError = class extends Error {
|
|
|
20202
20714
|
format() {
|
|
20203
20715
|
const formatted = {};
|
|
20204
20716
|
for (const error of this.errors) {
|
|
20205
|
-
const
|
|
20206
|
-
if (!formatted[
|
|
20207
|
-
formatted[
|
|
20717
|
+
const path36 = error.path.join(".");
|
|
20718
|
+
if (!formatted[path36]) {
|
|
20719
|
+
formatted[path36] = [];
|
|
20208
20720
|
}
|
|
20209
|
-
formatted[
|
|
20721
|
+
formatted[path36].push(error.message);
|
|
20210
20722
|
}
|
|
20211
20723
|
return formatted;
|
|
20212
20724
|
}
|