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