@lolyjs/core 0.3.0-alpha.5 → 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 +664 -161
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +664 -161
- package/dist/cli.mjs.map +1 -1
- package/dist/index.cjs +737 -234
- 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 +737 -234
- 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/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
|
}
|
|
@@ -16832,6 +16893,438 @@ async function renderErrorPageWithStream(errorPage, req, res, error, routeChunks
|
|
|
16832
16893
|
}
|
|
16833
16894
|
}
|
|
16834
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
|
+
|
|
16835
17328
|
// modules/server/routes.ts
|
|
16836
17329
|
init_globals();
|
|
16837
17330
|
|
|
@@ -16993,7 +17486,7 @@ function validateRealtimeConfig(config) {
|
|
|
16993
17486
|
}
|
|
16994
17487
|
|
|
16995
17488
|
// modules/server/routes.ts
|
|
16996
|
-
import
|
|
17489
|
+
import path29 from "path";
|
|
16997
17490
|
var cachedRewriteLoader = null;
|
|
16998
17491
|
var cachedProjectRoot = null;
|
|
16999
17492
|
var cachedIsDev = null;
|
|
@@ -17021,10 +17514,20 @@ function setupRoutes(options) {
|
|
|
17021
17514
|
} = options;
|
|
17022
17515
|
const routeChunks = routeLoader.loadRouteChunks();
|
|
17023
17516
|
const rewriteLoader = getRewriteLoader(projectRoot, isDev);
|
|
17024
|
-
const ssgOutDir =
|
|
17025
|
-
config ? getBuildDir(projectRoot, config) :
|
|
17517
|
+
const ssgOutDir = path29.join(
|
|
17518
|
+
config ? getBuildDir(projectRoot, config) : path29.join(projectRoot, BUILD_FOLDER_NAME),
|
|
17026
17519
|
"ssg"
|
|
17027
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
|
+
}
|
|
17028
17531
|
app.all("/api/*", async (req, res) => {
|
|
17029
17532
|
const apiRoutes = isDev && getRoutes ? (await getRoutes()).apiRoutes : initialApiRoutes;
|
|
17030
17533
|
const serverConfig = await getServerConfig(projectRoot);
|
|
@@ -18071,7 +18574,7 @@ import cors from "cors";
|
|
|
18071
18574
|
import helmet from "helmet";
|
|
18072
18575
|
import cookieParser from "cookie-parser";
|
|
18073
18576
|
import compression from "compression";
|
|
18074
|
-
import
|
|
18577
|
+
import crypto2 from "crypto";
|
|
18075
18578
|
var setupApplication = async ({
|
|
18076
18579
|
projectRoot
|
|
18077
18580
|
}) => {
|
|
@@ -18180,7 +18683,7 @@ var setupApplication = async ({
|
|
|
18180
18683
|
if (process.env.NODE_ENV !== "development" && security?.contentSecurityPolicy !== false) {
|
|
18181
18684
|
app.use(
|
|
18182
18685
|
(req, res, next) => {
|
|
18183
|
-
const nonce =
|
|
18686
|
+
const nonce = crypto2.randomBytes(16).toString("base64");
|
|
18184
18687
|
res.locals.nonce = nonce;
|
|
18185
18688
|
next();
|
|
18186
18689
|
}
|
|
@@ -18251,8 +18754,8 @@ var setupApplication = async ({
|
|
|
18251
18754
|
|
|
18252
18755
|
// src/server.ts
|
|
18253
18756
|
import dotenv2 from "dotenv";
|
|
18254
|
-
var envPath =
|
|
18255
|
-
if (
|
|
18757
|
+
var envPath = path30.join(process.cwd(), ".env");
|
|
18758
|
+
if (fs23.existsSync(envPath)) {
|
|
18256
18759
|
dotenv2.config({ path: envPath });
|
|
18257
18760
|
} else {
|
|
18258
18761
|
dotenv2.config();
|
|
@@ -18273,8 +18776,8 @@ async function startServer(options = {}) {
|
|
|
18273
18776
|
}
|
|
18274
18777
|
const port = options.port ?? (process.env.PORT ? parseInt(process.env.PORT, 10) : void 0) ?? config.server.port;
|
|
18275
18778
|
const host = process.env.HOST ?? (!isDev ? "0.0.0.0" : void 0) ?? config.server.host;
|
|
18276
|
-
const appDir = options.appDir ?? (isDev ? getAppDir(projectRoot, config) :
|
|
18277
|
-
if (!isDev && !
|
|
18779
|
+
const appDir = options.appDir ?? (isDev ? getAppDir(projectRoot, config) : path30.join(getBuildDir(projectRoot, config), "server"));
|
|
18780
|
+
if (!isDev && !fs23.existsSync(appDir)) {
|
|
18278
18781
|
logger4.error("Compiled directory not found", void 0, {
|
|
18279
18782
|
buildDir: config.directories.build,
|
|
18280
18783
|
appDir,
|
|
@@ -18345,14 +18848,14 @@ async function startProdServer(options = {}) {
|
|
|
18345
18848
|
}
|
|
18346
18849
|
|
|
18347
18850
|
// modules/build/index.ts
|
|
18348
|
-
import
|
|
18349
|
-
import
|
|
18851
|
+
import path35 from "path";
|
|
18852
|
+
import fs26 from "fs";
|
|
18350
18853
|
|
|
18351
18854
|
// modules/build/ssg/builder.ts
|
|
18352
|
-
import
|
|
18855
|
+
import path33 from "path";
|
|
18353
18856
|
|
|
18354
18857
|
// modules/build/ssg/path.ts
|
|
18355
|
-
import
|
|
18858
|
+
import path31 from "path";
|
|
18356
18859
|
function buildPathFromPattern(pattern, params) {
|
|
18357
18860
|
const segments = pattern.split("/").filter(Boolean);
|
|
18358
18861
|
const parts = [];
|
|
@@ -18381,12 +18884,12 @@ function buildPathFromPattern(pattern, params) {
|
|
|
18381
18884
|
}
|
|
18382
18885
|
function pathToOutDir(baseDir, urlPath) {
|
|
18383
18886
|
const clean = urlPath === "/" ? "" : urlPath.replace(/^\/+/, "");
|
|
18384
|
-
return
|
|
18887
|
+
return path31.join(baseDir, clean);
|
|
18385
18888
|
}
|
|
18386
18889
|
|
|
18387
18890
|
// modules/build/ssg/renderer.ts
|
|
18388
|
-
import
|
|
18389
|
-
import
|
|
18891
|
+
import fs24 from "fs";
|
|
18892
|
+
import path32 from "path";
|
|
18390
18893
|
import { renderToString } from "react-dom/server";
|
|
18391
18894
|
init_globals();
|
|
18392
18895
|
async function renderStaticRoute(projectRoot, ssgOutDir, route, urlPath, params, config) {
|
|
@@ -18522,16 +19025,16 @@ async function renderStaticRoute(projectRoot, ssgOutDir, route, urlPath, params,
|
|
|
18522
19025
|
const html = "<!DOCTYPE html>" + renderToString(documentTree);
|
|
18523
19026
|
const dir = pathToOutDir(ssgOutDir, urlPath);
|
|
18524
19027
|
ensureDir(dir);
|
|
18525
|
-
const htmlFile =
|
|
18526
|
-
const dataFile =
|
|
18527
|
-
|
|
18528
|
-
|
|
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");
|
|
18529
19032
|
}
|
|
18530
19033
|
|
|
18531
19034
|
// modules/build/ssg/builder.ts
|
|
18532
19035
|
init_globals();
|
|
18533
19036
|
async function buildStaticPages(projectRoot, routes, config) {
|
|
18534
|
-
const ssgOutDir =
|
|
19037
|
+
const ssgOutDir = path33.join(projectRoot, BUILD_FOLDER_NAME, "ssg");
|
|
18535
19038
|
ensureDir(ssgOutDir);
|
|
18536
19039
|
for (const route of routes) {
|
|
18537
19040
|
if (route.dynamic !== "force-static") continue;
|
|
@@ -18586,36 +19089,36 @@ async function buildStaticPages(projectRoot, routes, config) {
|
|
|
18586
19089
|
}
|
|
18587
19090
|
|
|
18588
19091
|
// modules/build/bundler/server.ts
|
|
18589
|
-
import
|
|
18590
|
-
import
|
|
19092
|
+
import path34 from "path";
|
|
19093
|
+
import fs25 from "fs";
|
|
18591
19094
|
import esbuild from "esbuild";
|
|
18592
19095
|
init_globals();
|
|
18593
19096
|
var SERVER_FILES = [INIT_FILE_NAME, CONFIG_FILE_NAME];
|
|
18594
19097
|
function createPathAliasPlugin(projectRoot, outDir) {
|
|
18595
19098
|
const aliases = loadAliasesFromTsconfig(projectRoot);
|
|
18596
|
-
const tsconfigPath =
|
|
19099
|
+
const tsconfigPath = path34.join(projectRoot, "tsconfig.json");
|
|
18597
19100
|
let baseUrl = ".";
|
|
18598
|
-
if (
|
|
19101
|
+
if (fs25.existsSync(tsconfigPath)) {
|
|
18599
19102
|
try {
|
|
18600
|
-
const tsconfig = JSON.parse(
|
|
19103
|
+
const tsconfig = JSON.parse(fs25.readFileSync(tsconfigPath, "utf-8"));
|
|
18601
19104
|
baseUrl = tsconfig.compilerOptions?.baseUrl ?? ".";
|
|
18602
19105
|
} catch {
|
|
18603
19106
|
}
|
|
18604
19107
|
}
|
|
18605
19108
|
function resolveAliasToRelative(importPath, sourceFile) {
|
|
18606
|
-
if (importPath.startsWith(".") || importPath.startsWith("/") ||
|
|
19109
|
+
if (importPath.startsWith(".") || importPath.startsWith("/") || path34.isAbsolute(importPath) || importPath.includes("node_modules")) {
|
|
18607
19110
|
return null;
|
|
18608
19111
|
}
|
|
18609
19112
|
for (const [aliasKey, aliasPath] of Object.entries(aliases)) {
|
|
18610
19113
|
if (importPath.startsWith(aliasKey + "/") || importPath === aliasKey) {
|
|
18611
19114
|
const restPath = importPath.startsWith(aliasKey + "/") ? importPath.slice(aliasKey.length + 1) : "";
|
|
18612
|
-
const resolvedPath = restPath ?
|
|
19115
|
+
const resolvedPath = restPath ? path34.join(aliasPath, restPath) : aliasPath;
|
|
18613
19116
|
let actualPath = null;
|
|
18614
19117
|
const extensions = [".ts", ".tsx", ".js", ".jsx", ".json"];
|
|
18615
|
-
if (
|
|
19118
|
+
if (fs25.existsSync(resolvedPath) && fs25.statSync(resolvedPath).isDirectory()) {
|
|
18616
19119
|
for (const ext of extensions) {
|
|
18617
|
-
const indexPath =
|
|
18618
|
-
if (
|
|
19120
|
+
const indexPath = path34.join(resolvedPath, `index${ext}`);
|
|
19121
|
+
if (fs25.existsSync(indexPath)) {
|
|
18619
19122
|
actualPath = indexPath;
|
|
18620
19123
|
break;
|
|
18621
19124
|
}
|
|
@@ -18623,20 +19126,20 @@ function createPathAliasPlugin(projectRoot, outDir) {
|
|
|
18623
19126
|
} else {
|
|
18624
19127
|
for (const ext of extensions) {
|
|
18625
19128
|
const filePath = resolvedPath + ext;
|
|
18626
|
-
if (
|
|
19129
|
+
if (fs25.existsSync(filePath)) {
|
|
18627
19130
|
actualPath = filePath;
|
|
18628
19131
|
break;
|
|
18629
19132
|
}
|
|
18630
19133
|
}
|
|
18631
|
-
if (!actualPath &&
|
|
19134
|
+
if (!actualPath && fs25.existsSync(resolvedPath)) {
|
|
18632
19135
|
actualPath = resolvedPath;
|
|
18633
19136
|
}
|
|
18634
19137
|
}
|
|
18635
19138
|
if (actualPath) {
|
|
18636
|
-
const relativePath =
|
|
19139
|
+
const relativePath = path34.relative(outDir, actualPath);
|
|
18637
19140
|
const normalizedPath = relativePath.replace(/\\/g, "/");
|
|
18638
19141
|
const finalPath = normalizedPath.startsWith(".") ? normalizedPath : `./${normalizedPath}`;
|
|
18639
|
-
const ext =
|
|
19142
|
+
const ext = path34.extname(finalPath);
|
|
18640
19143
|
const pathWithoutExt = ext === ".json" ? finalPath : finalPath.slice(0, -ext.length);
|
|
18641
19144
|
return pathWithoutExt;
|
|
18642
19145
|
}
|
|
@@ -18648,19 +19151,19 @@ function createPathAliasPlugin(projectRoot, outDir) {
|
|
|
18648
19151
|
name: "path-alias-resolver",
|
|
18649
19152
|
setup(build) {
|
|
18650
19153
|
function resolveAliasToAbsolute(importPath) {
|
|
18651
|
-
if (importPath.startsWith(".") || importPath.startsWith("/") ||
|
|
19154
|
+
if (importPath.startsWith(".") || importPath.startsWith("/") || path34.isAbsolute(importPath) || importPath.includes("node_modules")) {
|
|
18652
19155
|
return null;
|
|
18653
19156
|
}
|
|
18654
19157
|
for (const [aliasKey, aliasPath] of Object.entries(aliases)) {
|
|
18655
19158
|
if (importPath.startsWith(aliasKey + "/") || importPath === aliasKey) {
|
|
18656
19159
|
const restPath = importPath.startsWith(aliasKey + "/") ? importPath.slice(aliasKey.length + 1) : "";
|
|
18657
|
-
const resolvedPath = restPath ?
|
|
19160
|
+
const resolvedPath = restPath ? path34.join(aliasPath, restPath) : aliasPath;
|
|
18658
19161
|
let actualPath = null;
|
|
18659
19162
|
const extensions = [".ts", ".tsx", ".js", ".jsx", ".json"];
|
|
18660
|
-
if (
|
|
19163
|
+
if (fs25.existsSync(resolvedPath) && fs25.statSync(resolvedPath).isDirectory()) {
|
|
18661
19164
|
for (const ext of extensions) {
|
|
18662
|
-
const indexPath =
|
|
18663
|
-
if (
|
|
19165
|
+
const indexPath = path34.join(resolvedPath, `index${ext}`);
|
|
19166
|
+
if (fs25.existsSync(indexPath)) {
|
|
18664
19167
|
actualPath = indexPath;
|
|
18665
19168
|
break;
|
|
18666
19169
|
}
|
|
@@ -18668,12 +19171,12 @@ function createPathAliasPlugin(projectRoot, outDir) {
|
|
|
18668
19171
|
} else {
|
|
18669
19172
|
for (const ext of extensions) {
|
|
18670
19173
|
const filePath = resolvedPath + ext;
|
|
18671
|
-
if (
|
|
19174
|
+
if (fs25.existsSync(filePath)) {
|
|
18672
19175
|
actualPath = filePath;
|
|
18673
19176
|
break;
|
|
18674
19177
|
}
|
|
18675
19178
|
}
|
|
18676
|
-
if (!actualPath &&
|
|
19179
|
+
if (!actualPath && fs25.existsSync(resolvedPath)) {
|
|
18677
19180
|
actualPath = resolvedPath;
|
|
18678
19181
|
}
|
|
18679
19182
|
}
|
|
@@ -18686,7 +19189,7 @@ function createPathAliasPlugin(projectRoot, outDir) {
|
|
|
18686
19189
|
}
|
|
18687
19190
|
build.onResolve({ filter: /^[^./]/ }, (args) => {
|
|
18688
19191
|
const absolutePath = resolveAliasToAbsolute(args.path);
|
|
18689
|
-
if (absolutePath &&
|
|
19192
|
+
if (absolutePath && fs25.existsSync(absolutePath)) {
|
|
18690
19193
|
return {
|
|
18691
19194
|
path: absolutePath,
|
|
18692
19195
|
namespace: "file"
|
|
@@ -18695,13 +19198,13 @@ function createPathAliasPlugin(projectRoot, outDir) {
|
|
|
18695
19198
|
return null;
|
|
18696
19199
|
});
|
|
18697
19200
|
build.onLoad({ filter: /\.(ts|tsx|js|jsx)$/ }, (args) => {
|
|
18698
|
-
const fileName =
|
|
19201
|
+
const fileName = path34.basename(args.path);
|
|
18699
19202
|
const isServerFile = SERVER_FILES.some((f) => fileName === `${f}.ts` || fileName === `${f}.tsx` || fileName === `${f}.js` || fileName === `${f}.jsx`);
|
|
18700
|
-
const isInProjectRoot =
|
|
19203
|
+
const isInProjectRoot = path34.dirname(args.path) === projectRoot;
|
|
18701
19204
|
if (!isServerFile || !isInProjectRoot) {
|
|
18702
19205
|
return null;
|
|
18703
19206
|
}
|
|
18704
|
-
const contents =
|
|
19207
|
+
const contents = fs25.readFileSync(args.path, "utf-8");
|
|
18705
19208
|
let transformed = contents;
|
|
18706
19209
|
const aliasPatterns = Object.keys(aliases).sort((a, b) => b.length - a.length);
|
|
18707
19210
|
for (const aliasKey of aliasPatterns) {
|
|
@@ -18721,7 +19224,7 @@ function createPathAliasPlugin(projectRoot, outDir) {
|
|
|
18721
19224
|
}
|
|
18722
19225
|
return {
|
|
18723
19226
|
contents: transformed,
|
|
18724
|
-
loader:
|
|
19227
|
+
loader: path34.extname(args.path).slice(1)
|
|
18725
19228
|
};
|
|
18726
19229
|
});
|
|
18727
19230
|
}
|
|
@@ -18733,13 +19236,13 @@ function rewritePathAliasesInOutput(outDir, projectRoot, appDir) {
|
|
|
18733
19236
|
for (const [aliasKey, aliasSourcePath] of Object.entries(aliases)) {
|
|
18734
19237
|
if (aliasPath.startsWith(aliasKey + "/") || aliasPath === aliasKey) {
|
|
18735
19238
|
const restPath = aliasPath.startsWith(aliasKey + "/") ? aliasPath.slice(aliasKey.length + 1) : "";
|
|
18736
|
-
const resolvedSourcePath = restPath ?
|
|
19239
|
+
const resolvedSourcePath = restPath ? path34.join(aliasSourcePath, restPath) : aliasSourcePath;
|
|
18737
19240
|
let actualSourcePath = null;
|
|
18738
19241
|
const extensions = [".ts", ".tsx", ".js", ".jsx", ".json"];
|
|
18739
|
-
if (
|
|
19242
|
+
if (fs25.existsSync(resolvedSourcePath) && fs25.statSync(resolvedSourcePath).isDirectory()) {
|
|
18740
19243
|
for (const ext of extensions) {
|
|
18741
|
-
const indexPath =
|
|
18742
|
-
if (
|
|
19244
|
+
const indexPath = path34.join(resolvedSourcePath, `index${ext}`);
|
|
19245
|
+
if (fs25.existsSync(indexPath)) {
|
|
18743
19246
|
actualSourcePath = indexPath;
|
|
18744
19247
|
break;
|
|
18745
19248
|
}
|
|
@@ -18747,21 +19250,21 @@ function rewritePathAliasesInOutput(outDir, projectRoot, appDir) {
|
|
|
18747
19250
|
} else {
|
|
18748
19251
|
for (const ext of extensions) {
|
|
18749
19252
|
const filePath = resolvedSourcePath + ext;
|
|
18750
|
-
if (
|
|
19253
|
+
if (fs25.existsSync(filePath)) {
|
|
18751
19254
|
actualSourcePath = filePath;
|
|
18752
19255
|
break;
|
|
18753
19256
|
}
|
|
18754
19257
|
}
|
|
18755
|
-
if (!actualSourcePath &&
|
|
19258
|
+
if (!actualSourcePath && fs25.existsSync(resolvedSourcePath)) {
|
|
18756
19259
|
actualSourcePath = resolvedSourcePath;
|
|
18757
19260
|
}
|
|
18758
19261
|
}
|
|
18759
19262
|
if (actualSourcePath) {
|
|
18760
|
-
const relativeFromApp =
|
|
18761
|
-
const outputPath =
|
|
19263
|
+
const relativeFromApp = path34.relative(appDir, actualSourcePath);
|
|
19264
|
+
const outputPath = path34.join(outDir, relativeFromApp);
|
|
18762
19265
|
const pathWithoutExt = outputPath.replace(/\.(ts|tsx|js|jsx|json)$/, "");
|
|
18763
19266
|
const compiledPath = pathWithoutExt + ".mjs";
|
|
18764
|
-
if (
|
|
19267
|
+
if (fs25.existsSync(compiledPath)) {
|
|
18765
19268
|
return compiledPath;
|
|
18766
19269
|
}
|
|
18767
19270
|
}
|
|
@@ -18770,17 +19273,17 @@ function rewritePathAliasesInOutput(outDir, projectRoot, appDir) {
|
|
|
18770
19273
|
return null;
|
|
18771
19274
|
}
|
|
18772
19275
|
function walkAndRewrite(dir) {
|
|
18773
|
-
if (!
|
|
18774
|
-
const items =
|
|
19276
|
+
if (!fs25.existsSync(dir)) return;
|
|
19277
|
+
const items = fs25.readdirSync(dir, { withFileTypes: true });
|
|
18775
19278
|
for (const item of items) {
|
|
18776
|
-
const full =
|
|
19279
|
+
const full = path34.join(dir, item.name);
|
|
18777
19280
|
if (item.isDirectory()) {
|
|
18778
19281
|
walkAndRewrite(full);
|
|
18779
19282
|
continue;
|
|
18780
19283
|
}
|
|
18781
19284
|
if (item.isFile() && full.endsWith(".mjs")) {
|
|
18782
19285
|
try {
|
|
18783
|
-
let content =
|
|
19286
|
+
let content = fs25.readFileSync(full, "utf-8");
|
|
18784
19287
|
let modified = false;
|
|
18785
19288
|
const aliasPatterns = Object.keys(aliases).sort((a, b) => b.length - a.length);
|
|
18786
19289
|
for (const aliasKey of aliasPatterns) {
|
|
@@ -18792,8 +19295,8 @@ function rewritePathAliasesInOutput(outDir, projectRoot, appDir) {
|
|
|
18792
19295
|
content = content.replace(aliasInQuotesPattern, (match, quote1, rest, quote2) => {
|
|
18793
19296
|
const fullAliasPath = aliasKey + (rest || "");
|
|
18794
19297
|
const resolvedOutputPath = resolveAliasToOutputPath(fullAliasPath);
|
|
18795
|
-
if (resolvedOutputPath &&
|
|
18796
|
-
const relativePath =
|
|
19298
|
+
if (resolvedOutputPath && fs25.existsSync(resolvedOutputPath)) {
|
|
19299
|
+
const relativePath = path34.relative(path34.dirname(full), resolvedOutputPath);
|
|
18797
19300
|
let normalizedPath = relativePath.replace(/\\/g, "/");
|
|
18798
19301
|
if (!normalizedPath.startsWith(".")) {
|
|
18799
19302
|
normalizedPath = `./${normalizedPath}`;
|
|
@@ -18806,7 +19309,7 @@ function rewritePathAliasesInOutput(outDir, projectRoot, appDir) {
|
|
|
18806
19309
|
});
|
|
18807
19310
|
}
|
|
18808
19311
|
if (modified) {
|
|
18809
|
-
|
|
19312
|
+
fs25.writeFileSync(full, content, "utf-8");
|
|
18810
19313
|
}
|
|
18811
19314
|
} catch (error) {
|
|
18812
19315
|
console.warn(`[framework] Warning: Could not rewrite path aliases in ${full}:`, error instanceof Error ? error.message : String(error));
|
|
@@ -18817,14 +19320,14 @@ function rewritePathAliasesInOutput(outDir, projectRoot, appDir) {
|
|
|
18817
19320
|
walkAndRewrite(outDir);
|
|
18818
19321
|
}
|
|
18819
19322
|
function copyStaticFilesFromApp(appDir, outDir) {
|
|
18820
|
-
if (!
|
|
19323
|
+
if (!fs25.existsSync(appDir)) return;
|
|
18821
19324
|
const sourceExtensions = [".ts", ".tsx", ".js", ".jsx", ".d.ts", ".map"];
|
|
18822
19325
|
function walk(srcDir, destDir) {
|
|
18823
|
-
if (!
|
|
18824
|
-
const items =
|
|
19326
|
+
if (!fs25.existsSync(srcDir)) return;
|
|
19327
|
+
const items = fs25.readdirSync(srcDir, { withFileTypes: true });
|
|
18825
19328
|
for (const item of items) {
|
|
18826
|
-
const srcPath =
|
|
18827
|
-
const destPath =
|
|
19329
|
+
const srcPath = path34.join(srcDir, item.name);
|
|
19330
|
+
const destPath = path34.join(destDir, item.name);
|
|
18828
19331
|
if (item.isDirectory()) {
|
|
18829
19332
|
if (item.name === "node_modules" || item.name.startsWith(".")) {
|
|
18830
19333
|
continue;
|
|
@@ -18834,10 +19337,10 @@ function copyStaticFilesFromApp(appDir, outDir) {
|
|
|
18834
19337
|
continue;
|
|
18835
19338
|
}
|
|
18836
19339
|
if (item.isFile()) {
|
|
18837
|
-
const ext =
|
|
19340
|
+
const ext = path34.extname(item.name).toLowerCase();
|
|
18838
19341
|
if (!sourceExtensions.includes(ext)) {
|
|
18839
19342
|
ensureDir(destDir);
|
|
18840
|
-
|
|
19343
|
+
fs25.copyFileSync(srcPath, destPath);
|
|
18841
19344
|
}
|
|
18842
19345
|
}
|
|
18843
19346
|
}
|
|
@@ -18847,9 +19350,9 @@ function copyStaticFilesFromApp(appDir, outDir) {
|
|
|
18847
19350
|
function collectAppSources(appDir) {
|
|
18848
19351
|
const entries = [];
|
|
18849
19352
|
function walk(dir) {
|
|
18850
|
-
const items =
|
|
19353
|
+
const items = fs25.readdirSync(dir, { withFileTypes: true });
|
|
18851
19354
|
for (const item of items) {
|
|
18852
|
-
const full =
|
|
19355
|
+
const full = path34.join(dir, item.name);
|
|
18853
19356
|
if (item.isDirectory()) {
|
|
18854
19357
|
walk(full);
|
|
18855
19358
|
continue;
|
|
@@ -18866,7 +19369,7 @@ function collectAppSources(appDir) {
|
|
|
18866
19369
|
return entries;
|
|
18867
19370
|
}
|
|
18868
19371
|
async function buildServerApp(projectRoot, appDir, config) {
|
|
18869
|
-
const outDir =
|
|
19372
|
+
const outDir = path34.join(projectRoot, BUILD_FOLDER_NAME, "server");
|
|
18870
19373
|
const entryPoints = collectAppSources(appDir);
|
|
18871
19374
|
ensureDir(outDir);
|
|
18872
19375
|
if (entryPoints.length === 0) {
|
|
@@ -18885,7 +19388,7 @@ async function buildServerApp(projectRoot, appDir, config) {
|
|
|
18885
19388
|
bundle: true,
|
|
18886
19389
|
splitting: false,
|
|
18887
19390
|
logLevel: "info",
|
|
18888
|
-
tsconfig:
|
|
19391
|
+
tsconfig: path34.join(projectRoot, "tsconfig.json"),
|
|
18889
19392
|
packages: "external",
|
|
18890
19393
|
outExtension: { ".js": ".mjs" },
|
|
18891
19394
|
plugins: [pathAliasPlugin]
|
|
@@ -18894,9 +19397,9 @@ async function buildServerApp(projectRoot, appDir, config) {
|
|
|
18894
19397
|
copyStaticFilesFromApp(appDir, outDir);
|
|
18895
19398
|
rewritePathAliasesInOutput(outDir, projectRoot, appDir);
|
|
18896
19399
|
for (const fileName of SERVER_FILES) {
|
|
18897
|
-
const initTS =
|
|
18898
|
-
if (
|
|
18899
|
-
const initJSWithExt =
|
|
19400
|
+
const initTS = path34.join(projectRoot, `${fileName}.ts`);
|
|
19401
|
+
if (fs25.existsSync(initTS)) {
|
|
19402
|
+
const initJSWithExt = path34.join(outDir, `${fileName}.mjs`);
|
|
18900
19403
|
await esbuild.build({
|
|
18901
19404
|
entryPoints: [initTS],
|
|
18902
19405
|
outfile: initJSWithExt,
|
|
@@ -18908,7 +19411,7 @@ async function buildServerApp(projectRoot, appDir, config) {
|
|
|
18908
19411
|
bundle: true,
|
|
18909
19412
|
packages: "external",
|
|
18910
19413
|
logLevel: "info",
|
|
18911
|
-
tsconfig:
|
|
19414
|
+
tsconfig: path34.join(projectRoot, "tsconfig.json"),
|
|
18912
19415
|
plugins: [pathAliasPlugin],
|
|
18913
19416
|
outExtension: { ".js": ".mjs" }
|
|
18914
19417
|
});
|
|
@@ -18924,8 +19427,8 @@ async function buildApp(options = {}) {
|
|
|
18924
19427
|
const config = options.config ?? loadConfig(projectRoot);
|
|
18925
19428
|
const appDir = options.appDir ?? getAppDir(projectRoot, config);
|
|
18926
19429
|
try {
|
|
18927
|
-
const tsxPath =
|
|
18928
|
-
if (
|
|
19430
|
+
const tsxPath = path35.join(projectRoot, "node_modules", "tsx", "dist", "esm", "index.mjs");
|
|
19431
|
+
if (fs26.existsSync(tsxPath)) {
|
|
18929
19432
|
const { pathToFileURL: pathToFileURL2 } = await import("url");
|
|
18930
19433
|
const tsxUrl = pathToFileURL2(tsxPath).href;
|
|
18931
19434
|
await import(tsxUrl);
|
|
@@ -20211,11 +20714,11 @@ var ValidationError = class extends Error {
|
|
|
20211
20714
|
format() {
|
|
20212
20715
|
const formatted = {};
|
|
20213
20716
|
for (const error of this.errors) {
|
|
20214
|
-
const
|
|
20215
|
-
if (!formatted[
|
|
20216
|
-
formatted[
|
|
20717
|
+
const path36 = error.path.join(".");
|
|
20718
|
+
if (!formatted[path36]) {
|
|
20719
|
+
formatted[path36] = [];
|
|
20217
20720
|
}
|
|
20218
|
-
formatted[
|
|
20721
|
+
formatted[path36].push(error.message);
|
|
20219
20722
|
}
|
|
20220
20723
|
return formatted;
|
|
20221
20724
|
}
|