@lolyjs/core 0.2.0-alpha.27 → 0.2.0-alpha.28
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 +321 -0
- package/dist/cli.cjs +904 -315
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +898 -309
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +916 -316
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +38 -3
- package/dist/index.d.ts +38 -3
- package/dist/index.js +910 -310
- package/dist/index.js.map +1 -1
- package/dist/{index.types-DMOO-uvF.d.mts → index.types-B9j4OQft.d.mts} +1 -0
- package/dist/{index.types-DMOO-uvF.d.ts → index.types-B9j4OQft.d.ts} +1 -0
- package/dist/react/cache.cjs.map +1 -1
- package/dist/react/cache.d.mts +3 -1
- package/dist/react/cache.d.ts +3 -1
- package/dist/react/cache.js.map +1 -1
- package/dist/react/components.cjs.map +1 -1
- package/dist/react/components.js.map +1 -1
- package/dist/runtime.cjs +16 -5
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.js +16 -5
- package/dist/runtime.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -9904,8 +9904,8 @@ __export(src_exports, {
|
|
|
9904
9904
|
module.exports = __toCommonJS(src_exports);
|
|
9905
9905
|
|
|
9906
9906
|
// src/server.ts
|
|
9907
|
-
var
|
|
9908
|
-
var
|
|
9907
|
+
var import_fs21 = __toESM(require("fs"));
|
|
9908
|
+
var import_path27 = __toESM(require("path"));
|
|
9909
9909
|
|
|
9910
9910
|
// modules/server/utils/server-dir.ts
|
|
9911
9911
|
var import_fs = __toESM(require("fs"));
|
|
@@ -9945,8 +9945,8 @@ async function runInitIfExists(projectRoot, serverData) {
|
|
|
9945
9945
|
|
|
9946
9946
|
// modules/server/setup.ts
|
|
9947
9947
|
var import_express = __toESM(require("express"));
|
|
9948
|
-
var
|
|
9949
|
-
var
|
|
9948
|
+
var import_path21 = __toESM(require("path"));
|
|
9949
|
+
var import_fs19 = __toESM(require("fs"));
|
|
9950
9950
|
|
|
9951
9951
|
// modules/router/loader-pages.ts
|
|
9952
9952
|
var import_fs4 = __toESM(require("fs"));
|
|
@@ -9957,10 +9957,17 @@ var PAGE_FILE_REGEX = /^page\.(tsx|ts|jsx|js)$/;
|
|
|
9957
9957
|
var LAYOUT_FILE_BASENAME = "layout";
|
|
9958
9958
|
|
|
9959
9959
|
// modules/router/path.ts
|
|
9960
|
+
function isRouteGroup(dirName) {
|
|
9961
|
+
return dirName.startsWith("(") && dirName.endsWith(")");
|
|
9962
|
+
}
|
|
9960
9963
|
function buildRoutePathFromDir(relDir) {
|
|
9961
9964
|
if (!relDir || relDir === ".") return "/";
|
|
9962
9965
|
const clean = relDir.replace(/\\/g, "/");
|
|
9963
|
-
|
|
9966
|
+
const segments = clean.split("/").filter((seg) => {
|
|
9967
|
+
return !isRouteGroup(seg);
|
|
9968
|
+
});
|
|
9969
|
+
if (segments.length === 0) return "/";
|
|
9970
|
+
return "/" + segments.join("/");
|
|
9964
9971
|
}
|
|
9965
9972
|
function buildRegexFromRoutePath(routePath) {
|
|
9966
9973
|
const segments = routePath.split("/").filter(Boolean);
|
|
@@ -10176,13 +10183,17 @@ function validateRoutes(routes, appDir) {
|
|
|
10176
10183
|
}
|
|
10177
10184
|
for (const [pattern, duplicateRoutes] of routePatterns.entries()) {
|
|
10178
10185
|
if (duplicateRoutes.length > 1) {
|
|
10179
|
-
const files = duplicateRoutes.map(
|
|
10180
|
-
|
|
10181
|
-
|
|
10186
|
+
const files = duplicateRoutes.map((r) => {
|
|
10187
|
+
const relPath = r.pageFile ? import_path4.default.relative(appDir, r.pageFile) : "unknown";
|
|
10188
|
+
const segments = relPath.split(import_path4.default.sep);
|
|
10189
|
+
const hasRouteGroup = segments.some((seg) => isRouteGroup(seg));
|
|
10190
|
+
return hasRouteGroup ? `${relPath} (inside route group)` : relPath;
|
|
10191
|
+
}).join(", ");
|
|
10182
10192
|
errors.push(
|
|
10183
10193
|
`Duplicate route pattern "${pattern}" found in multiple files:
|
|
10184
10194
|
${files}
|
|
10185
|
-
\u{1F4A1} Suggestion:
|
|
10195
|
+
\u{1F4A1} Suggestion: Route groups (directories in parentheses) don't appear in URLs.
|
|
10196
|
+
Ensure each route has a unique path pattern after route groups are ignored.`
|
|
10186
10197
|
);
|
|
10187
10198
|
}
|
|
10188
10199
|
}
|
|
@@ -10459,12 +10470,13 @@ function loadApiRoutes(appDir) {
|
|
|
10459
10470
|
|
|
10460
10471
|
// modules/router/matcher.ts
|
|
10461
10472
|
function matchRoute(routes, urlPath) {
|
|
10473
|
+
const normalizedPath = urlPath.replace(/\/$/, "") || "/";
|
|
10462
10474
|
for (const route of routes) {
|
|
10463
|
-
const match = route.regex.exec(
|
|
10475
|
+
const match = route.regex.exec(normalizedPath);
|
|
10464
10476
|
if (!match) continue;
|
|
10465
10477
|
const params = {};
|
|
10466
10478
|
route.paramNames.forEach((name, idx) => {
|
|
10467
|
-
params[name] = match[idx + 1];
|
|
10479
|
+
params[name] = decodeURIComponent(match[idx + 1] || "");
|
|
10468
10480
|
});
|
|
10469
10481
|
return { route, params };
|
|
10470
10482
|
}
|
|
@@ -11474,34 +11486,504 @@ function loadErrorRouteFromFilesystem(appDir) {
|
|
|
11474
11486
|
};
|
|
11475
11487
|
}
|
|
11476
11488
|
|
|
11489
|
+
// modules/router/rewrites.ts
|
|
11490
|
+
function parseRewritePattern(pattern) {
|
|
11491
|
+
const cleanPattern = pattern.replace(/^\/+|\/+$/g, "") || "";
|
|
11492
|
+
if (!cleanPattern) {
|
|
11493
|
+
return {
|
|
11494
|
+
regex: /^\/?$/,
|
|
11495
|
+
paramNames: []
|
|
11496
|
+
};
|
|
11497
|
+
}
|
|
11498
|
+
const segments = cleanPattern.split("/").filter(Boolean);
|
|
11499
|
+
const paramNames = [];
|
|
11500
|
+
const regexParts = [];
|
|
11501
|
+
for (let i = 0; i < segments.length; i++) {
|
|
11502
|
+
const seg = segments[i];
|
|
11503
|
+
if (seg === "*") {
|
|
11504
|
+
if (i !== segments.length - 1) {
|
|
11505
|
+
throw new Error(
|
|
11506
|
+
`Catch-all "*" in "${pattern}" must be the last segment.`
|
|
11507
|
+
);
|
|
11508
|
+
}
|
|
11509
|
+
regexParts.push("(.+)");
|
|
11510
|
+
continue;
|
|
11511
|
+
}
|
|
11512
|
+
if (seg.endsWith("*") && seg.startsWith(":")) {
|
|
11513
|
+
const paramName = seg.slice(1, -1);
|
|
11514
|
+
if (i !== segments.length - 1) {
|
|
11515
|
+
throw new Error(
|
|
11516
|
+
`Catch-all segment "${seg}" in "${pattern}" must be the last segment.`
|
|
11517
|
+
);
|
|
11518
|
+
}
|
|
11519
|
+
paramNames.push(paramName);
|
|
11520
|
+
regexParts.push("(.+)");
|
|
11521
|
+
continue;
|
|
11522
|
+
}
|
|
11523
|
+
if (seg.startsWith(":") && seg.length > 1) {
|
|
11524
|
+
const paramName = seg.slice(1);
|
|
11525
|
+
paramNames.push(paramName);
|
|
11526
|
+
regexParts.push("([^/]+)");
|
|
11527
|
+
continue;
|
|
11528
|
+
}
|
|
11529
|
+
const escaped = seg.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
11530
|
+
regexParts.push(escaped);
|
|
11531
|
+
}
|
|
11532
|
+
const regexSource = "^/?" + regexParts.join("/") + "/?$";
|
|
11533
|
+
const regex = new RegExp(regexSource);
|
|
11534
|
+
return { regex, paramNames };
|
|
11535
|
+
}
|
|
11536
|
+
function extractHostParams(hostPattern, actualHost) {
|
|
11537
|
+
const regexPattern = hostPattern.replace(/:([^.]+)/g, "([^.]+)").replace(/\./g, "\\.").replace(/\*/g, ".*");
|
|
11538
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
|
11539
|
+
const match = regex.exec(actualHost);
|
|
11540
|
+
if (!match) return null;
|
|
11541
|
+
const paramNames = [];
|
|
11542
|
+
const paramPattern = /:([^.]+)/g;
|
|
11543
|
+
let paramMatch;
|
|
11544
|
+
while ((paramMatch = paramPattern.exec(hostPattern)) !== null) {
|
|
11545
|
+
paramNames.push(paramMatch[1]);
|
|
11546
|
+
}
|
|
11547
|
+
const params = {};
|
|
11548
|
+
paramNames.forEach((name, idx) => {
|
|
11549
|
+
params[name] = match[idx + 1] || "";
|
|
11550
|
+
});
|
|
11551
|
+
return params;
|
|
11552
|
+
}
|
|
11553
|
+
function evaluateRewriteConditions(conditions, req) {
|
|
11554
|
+
const extractedParams = {};
|
|
11555
|
+
for (const condition of conditions) {
|
|
11556
|
+
switch (condition.type) {
|
|
11557
|
+
case "host": {
|
|
11558
|
+
const hostWithPort = req.get("host") || req.hostname || req.get("x-forwarded-host")?.split(",")[0] || "";
|
|
11559
|
+
const host = hostWithPort.split(":")[0];
|
|
11560
|
+
if (process.env.NODE_ENV === "development") {
|
|
11561
|
+
console.log("[rewrites] Host matching:", {
|
|
11562
|
+
pattern: condition.value,
|
|
11563
|
+
actualHost: host,
|
|
11564
|
+
hostWithPort,
|
|
11565
|
+
reqHost: req.get("host"),
|
|
11566
|
+
reqHostname: req.hostname
|
|
11567
|
+
});
|
|
11568
|
+
}
|
|
11569
|
+
const hostParams = extractHostParams(condition.value, host);
|
|
11570
|
+
if (!hostParams) {
|
|
11571
|
+
if (process.env.NODE_ENV === "development") {
|
|
11572
|
+
console.log("[rewrites] Host params extraction failed:", {
|
|
11573
|
+
pattern: condition.value,
|
|
11574
|
+
actualHost: host
|
|
11575
|
+
});
|
|
11576
|
+
}
|
|
11577
|
+
return { matches: false, params: {} };
|
|
11578
|
+
}
|
|
11579
|
+
Object.assign(extractedParams, hostParams);
|
|
11580
|
+
break;
|
|
11581
|
+
}
|
|
11582
|
+
case "header": {
|
|
11583
|
+
if (!condition.key) {
|
|
11584
|
+
return { matches: false, params: {} };
|
|
11585
|
+
}
|
|
11586
|
+
const headerValue = req.get(condition.key.toLowerCase());
|
|
11587
|
+
if (!headerValue || headerValue !== condition.value) {
|
|
11588
|
+
return { matches: false, params: {} };
|
|
11589
|
+
}
|
|
11590
|
+
break;
|
|
11591
|
+
}
|
|
11592
|
+
case "cookie": {
|
|
11593
|
+
if (!condition.key) {
|
|
11594
|
+
return { matches: false, params: {} };
|
|
11595
|
+
}
|
|
11596
|
+
const cookieValue = req.cookies?.[condition.key];
|
|
11597
|
+
if (!cookieValue || cookieValue !== condition.value) {
|
|
11598
|
+
return { matches: false, params: {} };
|
|
11599
|
+
}
|
|
11600
|
+
break;
|
|
11601
|
+
}
|
|
11602
|
+
case "query": {
|
|
11603
|
+
if (!condition.key) {
|
|
11604
|
+
return { matches: false, params: {} };
|
|
11605
|
+
}
|
|
11606
|
+
const queryValue = req.query[condition.key];
|
|
11607
|
+
if (!queryValue || String(queryValue) !== condition.value) {
|
|
11608
|
+
return { matches: false, params: {} };
|
|
11609
|
+
}
|
|
11610
|
+
break;
|
|
11611
|
+
}
|
|
11612
|
+
default:
|
|
11613
|
+
return { matches: false, params: {} };
|
|
11614
|
+
}
|
|
11615
|
+
}
|
|
11616
|
+
return { matches: true, params: extractedParams };
|
|
11617
|
+
}
|
|
11618
|
+
function replaceDestinationParams(destination, params) {
|
|
11619
|
+
let result = destination;
|
|
11620
|
+
for (const [key, value] of Object.entries(params)) {
|
|
11621
|
+
const pattern = new RegExp(`:${key}(?:\\*)?`, "g");
|
|
11622
|
+
result = result.replace(pattern, value);
|
|
11623
|
+
}
|
|
11624
|
+
return result;
|
|
11625
|
+
}
|
|
11626
|
+
async function processRewrites(urlPath, compiledRewrites, req) {
|
|
11627
|
+
const normalizedPath = urlPath.replace(/\/$/, "") || "/";
|
|
11628
|
+
if (normalizedPath.startsWith("/static/") || // Static assets (client.js, client.css, etc.)
|
|
11629
|
+
normalizedPath.startsWith("/__fw/") || // Framework internal routes (hot reload, etc.)
|
|
11630
|
+
normalizedPath === "/favicon.ico" || // Favicon
|
|
11631
|
+
normalizedPath.startsWith("/wss/")) {
|
|
11632
|
+
if (process.env.NODE_ENV === "development") {
|
|
11633
|
+
console.log("[rewrites] Skipping rewrite for system route:", normalizedPath);
|
|
11634
|
+
}
|
|
11635
|
+
return null;
|
|
11636
|
+
}
|
|
11637
|
+
if (process.env.NODE_ENV === "development") {
|
|
11638
|
+
console.log("[rewrites] Processing rewrites:", {
|
|
11639
|
+
urlPath,
|
|
11640
|
+
normalizedPath,
|
|
11641
|
+
host: req.get("host"),
|
|
11642
|
+
hostname: req.hostname,
|
|
11643
|
+
compiledRewritesCount: compiledRewrites.length
|
|
11644
|
+
});
|
|
11645
|
+
}
|
|
11646
|
+
for (const rewrite of compiledRewrites) {
|
|
11647
|
+
let conditionParams = {};
|
|
11648
|
+
if (rewrite.has && rewrite.has.length > 0) {
|
|
11649
|
+
const conditionResult = evaluateRewriteConditions(rewrite.has, req);
|
|
11650
|
+
if (!conditionResult.matches) {
|
|
11651
|
+
if (process.env.NODE_ENV === "development") {
|
|
11652
|
+
console.log("[rewrites] Condition not matched:", {
|
|
11653
|
+
source: rewrite.source,
|
|
11654
|
+
conditions: rewrite.has
|
|
11655
|
+
});
|
|
11656
|
+
}
|
|
11657
|
+
continue;
|
|
11658
|
+
}
|
|
11659
|
+
conditionParams = conditionResult.params;
|
|
11660
|
+
if (process.env.NODE_ENV === "development") {
|
|
11661
|
+
console.log("[rewrites] Condition matched:", {
|
|
11662
|
+
source: rewrite.source,
|
|
11663
|
+
conditionParams
|
|
11664
|
+
});
|
|
11665
|
+
}
|
|
11666
|
+
}
|
|
11667
|
+
const sourceMatch = rewrite.sourceRegex.exec(normalizedPath);
|
|
11668
|
+
if (!sourceMatch) {
|
|
11669
|
+
if (process.env.NODE_ENV === "development") {
|
|
11670
|
+
console.log("[rewrites] Source pattern not matched:", {
|
|
11671
|
+
source: rewrite.source,
|
|
11672
|
+
normalizedPath,
|
|
11673
|
+
sourceRegex: rewrite.sourceRegex.toString()
|
|
11674
|
+
});
|
|
11675
|
+
}
|
|
11676
|
+
continue;
|
|
11677
|
+
}
|
|
11678
|
+
if (process.env.NODE_ENV === "development") {
|
|
11679
|
+
console.log("[rewrites] Source pattern matched:", {
|
|
11680
|
+
source: rewrite.source,
|
|
11681
|
+
normalizedPath,
|
|
11682
|
+
match: sourceMatch[0]
|
|
11683
|
+
});
|
|
11684
|
+
}
|
|
11685
|
+
const sourceParams = {};
|
|
11686
|
+
rewrite.sourceParamNames.forEach((name, idx) => {
|
|
11687
|
+
sourceParams[name] = decodeURIComponent(sourceMatch[idx + 1] || "");
|
|
11688
|
+
});
|
|
11689
|
+
const allParams = { ...sourceParams, ...conditionParams };
|
|
11690
|
+
let destination;
|
|
11691
|
+
if (typeof rewrite.destination === "function") {
|
|
11692
|
+
destination = await rewrite.destination(allParams, req);
|
|
11693
|
+
} else {
|
|
11694
|
+
destination = replaceDestinationParams(rewrite.destination, allParams);
|
|
11695
|
+
}
|
|
11696
|
+
const normalizedDestination = destination.replace(/\/+/g, "/").replace(/^([^/])/, "/$1").replace(/\/$/, "") || "/";
|
|
11697
|
+
if (process.env.NODE_ENV === "development") {
|
|
11698
|
+
console.log("[rewrites] Rewrite successful:", {
|
|
11699
|
+
originalPath: urlPath,
|
|
11700
|
+
rewrittenPath: normalizedDestination,
|
|
11701
|
+
allParams
|
|
11702
|
+
});
|
|
11703
|
+
}
|
|
11704
|
+
return {
|
|
11705
|
+
rewrittenPath: normalizedDestination,
|
|
11706
|
+
extractedParams: allParams
|
|
11707
|
+
};
|
|
11708
|
+
}
|
|
11709
|
+
return null;
|
|
11710
|
+
}
|
|
11711
|
+
function validateRewrites(rules) {
|
|
11712
|
+
for (const rule of rules) {
|
|
11713
|
+
if (typeof rule.destination === "string") {
|
|
11714
|
+
if (rule.source === rule.destination) {
|
|
11715
|
+
console.warn(
|
|
11716
|
+
`[framework][rewrites] Rewrite rule has identical source and destination: "${rule.source}". This may cause issues.`
|
|
11717
|
+
);
|
|
11718
|
+
}
|
|
11719
|
+
}
|
|
11720
|
+
}
|
|
11721
|
+
const sources = /* @__PURE__ */ new Set();
|
|
11722
|
+
for (const rule of rules) {
|
|
11723
|
+
if (sources.has(rule.source)) {
|
|
11724
|
+
console.warn(
|
|
11725
|
+
`[framework][rewrites] Duplicate rewrite source pattern: "${rule.source}". Only the first match will be used.`
|
|
11726
|
+
);
|
|
11727
|
+
}
|
|
11728
|
+
sources.add(rule.source);
|
|
11729
|
+
}
|
|
11730
|
+
}
|
|
11731
|
+
function compileRewriteRules(rules) {
|
|
11732
|
+
validateRewrites(rules);
|
|
11733
|
+
return rules.map((rule) => {
|
|
11734
|
+
const { regex, paramNames } = parseRewritePattern(rule.source);
|
|
11735
|
+
let hostRegex;
|
|
11736
|
+
let hostParamNames;
|
|
11737
|
+
if (rule.has) {
|
|
11738
|
+
const hostCondition = rule.has.find((c) => c.type === "host");
|
|
11739
|
+
if (hostCondition) {
|
|
11740
|
+
const hostPattern = hostCondition.value;
|
|
11741
|
+
const hostRegexPattern = hostPattern.replace(/:([^.]+)/g, "([^.]+)").replace(/\./g, "\\.").replace(/\*/g, ".*");
|
|
11742
|
+
hostRegex = new RegExp(`^${hostRegexPattern}$`);
|
|
11743
|
+
hostParamNames = [];
|
|
11744
|
+
const paramPattern = /:([^.]+)/g;
|
|
11745
|
+
let paramMatch;
|
|
11746
|
+
while ((paramMatch = paramPattern.exec(hostPattern)) !== null) {
|
|
11747
|
+
hostParamNames.push(paramMatch[1]);
|
|
11748
|
+
}
|
|
11749
|
+
}
|
|
11750
|
+
}
|
|
11751
|
+
return {
|
|
11752
|
+
source: rule.source,
|
|
11753
|
+
sourceRegex: regex,
|
|
11754
|
+
sourceParamNames: paramNames,
|
|
11755
|
+
destination: rule.destination,
|
|
11756
|
+
has: rule.has,
|
|
11757
|
+
hostRegex,
|
|
11758
|
+
hostParamNames
|
|
11759
|
+
};
|
|
11760
|
+
});
|
|
11761
|
+
}
|
|
11762
|
+
|
|
11763
|
+
// modules/router/rewrites-loader.ts
|
|
11764
|
+
var import_fs11 = __toESM(require("fs"));
|
|
11765
|
+
var import_path13 = __toESM(require("path"));
|
|
11766
|
+
var FilesystemRewriteLoader = class {
|
|
11767
|
+
// Maximum cache age in ms (1 second fallback)
|
|
11768
|
+
constructor(projectRoot) {
|
|
11769
|
+
this.projectRoot = projectRoot;
|
|
11770
|
+
this.cache = null;
|
|
11771
|
+
this.cacheMaxAge = 1e3;
|
|
11772
|
+
}
|
|
11773
|
+
/**
|
|
11774
|
+
* Invalidates the cache, forcing a reload on next access.
|
|
11775
|
+
*/
|
|
11776
|
+
invalidateCache() {
|
|
11777
|
+
this.cache = null;
|
|
11778
|
+
}
|
|
11779
|
+
/**
|
|
11780
|
+
* Finds the rewrites config file.
|
|
11781
|
+
* Looks for rewrites.config.ts, rewrites.config.js, or rewrites.config.json
|
|
11782
|
+
*/
|
|
11783
|
+
findRewritesConfig() {
|
|
11784
|
+
const candidates = [
|
|
11785
|
+
import_path13.default.join(this.projectRoot, "rewrites.config.ts"),
|
|
11786
|
+
import_path13.default.join(this.projectRoot, "rewrites.config.js"),
|
|
11787
|
+
import_path13.default.join(this.projectRoot, "rewrites.config.json")
|
|
11788
|
+
];
|
|
11789
|
+
for (const candidate of candidates) {
|
|
11790
|
+
if (import_fs11.default.existsSync(candidate)) {
|
|
11791
|
+
return candidate;
|
|
11792
|
+
}
|
|
11793
|
+
}
|
|
11794
|
+
return null;
|
|
11795
|
+
}
|
|
11796
|
+
/**
|
|
11797
|
+
* Checks if the rewrites config file has changed.
|
|
11798
|
+
*/
|
|
11799
|
+
hasConfigChanged(configPath) {
|
|
11800
|
+
if (!this.cache || !this.cache.fileStats) {
|
|
11801
|
+
return true;
|
|
11802
|
+
}
|
|
11803
|
+
if (!import_fs11.default.existsSync(configPath)) {
|
|
11804
|
+
return this.cache.rewrites.length > 0;
|
|
11805
|
+
}
|
|
11806
|
+
const stats = import_fs11.default.statSync(configPath);
|
|
11807
|
+
const cachedStats = this.cache.fileStats;
|
|
11808
|
+
return stats.mtimeMs !== cachedStats.mtime || stats.size !== cachedStats.size;
|
|
11809
|
+
}
|
|
11810
|
+
/**
|
|
11811
|
+
* Loads rewrites from a config file.
|
|
11812
|
+
*/
|
|
11813
|
+
async loadRewritesFromFile(configPath) {
|
|
11814
|
+
const ext = import_path13.default.extname(configPath);
|
|
11815
|
+
if (ext === ".json") {
|
|
11816
|
+
const content = import_fs11.default.readFileSync(configPath, "utf-8");
|
|
11817
|
+
const config2 = JSON.parse(content);
|
|
11818
|
+
return Array.isArray(config2) ? config2 : [];
|
|
11819
|
+
}
|
|
11820
|
+
delete require.cache[require.resolve(configPath)];
|
|
11821
|
+
const mod = require(configPath);
|
|
11822
|
+
const config = mod.default || mod;
|
|
11823
|
+
if (typeof config === "function") {
|
|
11824
|
+
return await config();
|
|
11825
|
+
}
|
|
11826
|
+
if (Array.isArray(config)) {
|
|
11827
|
+
return config;
|
|
11828
|
+
}
|
|
11829
|
+
throw new Error(
|
|
11830
|
+
`Invalid rewrites config in ${configPath}. Expected array or function returning array.`
|
|
11831
|
+
);
|
|
11832
|
+
}
|
|
11833
|
+
/**
|
|
11834
|
+
* Checks if cache is still valid, invalidates if config changed.
|
|
11835
|
+
*/
|
|
11836
|
+
ensureCacheValid() {
|
|
11837
|
+
if (!this.cache) {
|
|
11838
|
+
return;
|
|
11839
|
+
}
|
|
11840
|
+
const now = Date.now();
|
|
11841
|
+
if (now - this.cache.timestamp > this.cacheMaxAge) {
|
|
11842
|
+
const configPath = this.findRewritesConfig();
|
|
11843
|
+
if (configPath && this.hasConfigChanged(configPath)) {
|
|
11844
|
+
this.cache = null;
|
|
11845
|
+
} else {
|
|
11846
|
+
this.cache.timestamp = now;
|
|
11847
|
+
}
|
|
11848
|
+
}
|
|
11849
|
+
}
|
|
11850
|
+
async loadRewrites() {
|
|
11851
|
+
this.ensureCacheValid();
|
|
11852
|
+
const configPath = this.findRewritesConfig();
|
|
11853
|
+
if (!configPath) {
|
|
11854
|
+
if (this.cache && this.cache.rewrites.length === 0) {
|
|
11855
|
+
return this.cache.rewrites;
|
|
11856
|
+
}
|
|
11857
|
+
this.cache = {
|
|
11858
|
+
rewrites: [],
|
|
11859
|
+
fileStats: null,
|
|
11860
|
+
timestamp: Date.now()
|
|
11861
|
+
};
|
|
11862
|
+
return [];
|
|
11863
|
+
}
|
|
11864
|
+
if (!this.cache || this.hasConfigChanged(configPath)) {
|
|
11865
|
+
const rules = await this.loadRewritesFromFile(configPath);
|
|
11866
|
+
const compiled = compileRewriteRules(rules);
|
|
11867
|
+
const stats = import_fs11.default.statSync(configPath);
|
|
11868
|
+
const fileStats = {
|
|
11869
|
+
mtime: stats.mtimeMs,
|
|
11870
|
+
size: stats.size
|
|
11871
|
+
};
|
|
11872
|
+
this.cache = {
|
|
11873
|
+
rewrites: compiled,
|
|
11874
|
+
fileStats,
|
|
11875
|
+
timestamp: Date.now()
|
|
11876
|
+
};
|
|
11877
|
+
}
|
|
11878
|
+
return this.cache.rewrites;
|
|
11879
|
+
}
|
|
11880
|
+
};
|
|
11881
|
+
var ManifestRewriteLoader = class {
|
|
11882
|
+
constructor(projectRoot) {
|
|
11883
|
+
this.cache = null;
|
|
11884
|
+
this.manifestPath = import_path13.default.join(projectRoot, ".loly", "rewrites-manifest.json");
|
|
11885
|
+
}
|
|
11886
|
+
/**
|
|
11887
|
+
* Reads the rewrites manifest from disk.
|
|
11888
|
+
*/
|
|
11889
|
+
readManifest() {
|
|
11890
|
+
if (!import_fs11.default.existsSync(this.manifestPath)) {
|
|
11891
|
+
return null;
|
|
11892
|
+
}
|
|
11893
|
+
try {
|
|
11894
|
+
const content = import_fs11.default.readFileSync(this.manifestPath, "utf-8");
|
|
11895
|
+
return JSON.parse(content);
|
|
11896
|
+
} catch (error) {
|
|
11897
|
+
console.warn(
|
|
11898
|
+
`Failed to read rewrites manifest from ${this.manifestPath}:`,
|
|
11899
|
+
error
|
|
11900
|
+
);
|
|
11901
|
+
return null;
|
|
11902
|
+
}
|
|
11903
|
+
}
|
|
11904
|
+
async loadRewrites() {
|
|
11905
|
+
if (this.cache) {
|
|
11906
|
+
return this.cache;
|
|
11907
|
+
}
|
|
11908
|
+
const manifest = this.readManifest();
|
|
11909
|
+
if (!manifest || !manifest.rewrites) {
|
|
11910
|
+
this.cache = [];
|
|
11911
|
+
return [];
|
|
11912
|
+
}
|
|
11913
|
+
const compiled = compileRewriteRules(manifest.rewrites);
|
|
11914
|
+
this.cache = compiled;
|
|
11915
|
+
return compiled;
|
|
11916
|
+
}
|
|
11917
|
+
};
|
|
11918
|
+
function createRewriteLoader(projectRoot, isDev) {
|
|
11919
|
+
if (isDev) {
|
|
11920
|
+
return new FilesystemRewriteLoader(projectRoot);
|
|
11921
|
+
} else {
|
|
11922
|
+
return new ManifestRewriteLoader(projectRoot);
|
|
11923
|
+
}
|
|
11924
|
+
}
|
|
11925
|
+
|
|
11926
|
+
// modules/router/rewrites-manifest.ts
|
|
11927
|
+
var import_fs12 = __toESM(require("fs"));
|
|
11928
|
+
var import_path14 = __toESM(require("path"));
|
|
11929
|
+
init_globals();
|
|
11930
|
+
async function writeRewritesManifest(projectRoot) {
|
|
11931
|
+
const buildDir = import_path14.default.join(projectRoot, BUILD_FOLDER_NAME);
|
|
11932
|
+
if (!import_fs12.default.existsSync(buildDir)) {
|
|
11933
|
+
import_fs12.default.mkdirSync(buildDir, { recursive: true });
|
|
11934
|
+
}
|
|
11935
|
+
const manifestPath = import_path14.default.join(buildDir, "rewrites-manifest.json");
|
|
11936
|
+
const loader = createRewriteLoader(projectRoot, true);
|
|
11937
|
+
const compiledRewrites = await loader.loadRewrites();
|
|
11938
|
+
const serializableRules = [];
|
|
11939
|
+
for (const compiled of compiledRewrites) {
|
|
11940
|
+
if (typeof compiled.destination === "string") {
|
|
11941
|
+
serializableRules.push({
|
|
11942
|
+
source: compiled.source,
|
|
11943
|
+
destination: compiled.destination,
|
|
11944
|
+
has: compiled.has
|
|
11945
|
+
});
|
|
11946
|
+
} else {
|
|
11947
|
+
console.warn(
|
|
11948
|
+
`[framework][build] Rewrite with source "${compiled.source}" has a function destination and will not be included in the manifest. Only static rewrites are supported in production builds.`
|
|
11949
|
+
);
|
|
11950
|
+
}
|
|
11951
|
+
}
|
|
11952
|
+
const manifest = {
|
|
11953
|
+
version: 1,
|
|
11954
|
+
rewrites: serializableRules
|
|
11955
|
+
};
|
|
11956
|
+
import_fs12.default.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
11957
|
+
}
|
|
11958
|
+
|
|
11477
11959
|
// modules/build/bundler/client.ts
|
|
11478
11960
|
var import_core2 = require("@rspack/core");
|
|
11479
11961
|
|
|
11480
11962
|
// modules/build/config/client.ts
|
|
11481
|
-
var
|
|
11482
|
-
var
|
|
11963
|
+
var import_path16 = __toESM(require("path"));
|
|
11964
|
+
var import_fs14 = __toESM(require("fs"));
|
|
11483
11965
|
var import_core = require("@rspack/core");
|
|
11484
11966
|
|
|
11485
11967
|
// modules/build/utils/index.ts
|
|
11486
|
-
var
|
|
11487
|
-
var
|
|
11968
|
+
var import_fs13 = __toESM(require("fs"));
|
|
11969
|
+
var import_path15 = __toESM(require("path"));
|
|
11488
11970
|
function ensureDir(dir) {
|
|
11489
|
-
|
|
11971
|
+
import_fs13.default.mkdirSync(dir, { recursive: true });
|
|
11490
11972
|
}
|
|
11491
11973
|
function loadAliasesFromTsconfig(projectRoot) {
|
|
11492
|
-
const tsconfigPath =
|
|
11974
|
+
const tsconfigPath = import_path15.default.join(projectRoot, "tsconfig.json");
|
|
11493
11975
|
const aliases = {};
|
|
11494
|
-
if (!
|
|
11495
|
-
aliases["@app"] =
|
|
11976
|
+
if (!import_fs13.default.existsSync(tsconfigPath)) {
|
|
11977
|
+
aliases["@app"] = import_path15.default.resolve(projectRoot, "app");
|
|
11496
11978
|
return aliases;
|
|
11497
11979
|
}
|
|
11498
11980
|
let tsconfig;
|
|
11499
11981
|
try {
|
|
11500
|
-
tsconfig = JSON.parse(
|
|
11982
|
+
tsconfig = JSON.parse(import_fs13.default.readFileSync(tsconfigPath, "utf-8"));
|
|
11501
11983
|
} catch (err) {
|
|
11502
11984
|
console.warn("\u26A0\uFE0F [framework] Could not read tsconfig.json:", err instanceof Error ? err.message : String(err));
|
|
11503
11985
|
console.warn("\u{1F4A1} Using default path aliases. For custom aliases, ensure tsconfig.json is valid.");
|
|
11504
|
-
aliases["@app"] =
|
|
11986
|
+
aliases["@app"] = import_path15.default.resolve(projectRoot, "app");
|
|
11505
11987
|
return aliases;
|
|
11506
11988
|
}
|
|
11507
11989
|
const compilerOptions = tsconfig.compilerOptions ?? {};
|
|
@@ -11512,40 +11994,40 @@ function loadAliasesFromTsconfig(projectRoot) {
|
|
|
11512
11994
|
const aliasKey = aliasPattern.replace(/\/\*$/, "");
|
|
11513
11995
|
const firstTarget = targets[0];
|
|
11514
11996
|
const targetPath = firstTarget.replace(/\/\*$/, "");
|
|
11515
|
-
const resolved =
|
|
11997
|
+
const resolved = import_path15.default.resolve(projectRoot, baseUrl, targetPath);
|
|
11516
11998
|
aliases[aliasKey] = resolved;
|
|
11517
11999
|
}
|
|
11518
12000
|
if (!aliases["@app"]) {
|
|
11519
|
-
aliases["@app"] =
|
|
12001
|
+
aliases["@app"] = import_path15.default.resolve(projectRoot, "app");
|
|
11520
12002
|
}
|
|
11521
12003
|
return aliases;
|
|
11522
12004
|
}
|
|
11523
12005
|
function copyDirRecursive(srcDir, destDir) {
|
|
11524
|
-
if (!
|
|
12006
|
+
if (!import_fs13.default.existsSync(srcDir)) return;
|
|
11525
12007
|
ensureDir(destDir);
|
|
11526
|
-
const entries =
|
|
12008
|
+
const entries = import_fs13.default.readdirSync(srcDir, { withFileTypes: true });
|
|
11527
12009
|
for (const entry of entries) {
|
|
11528
|
-
const srcPath =
|
|
11529
|
-
const destPath =
|
|
12010
|
+
const srcPath = import_path15.default.join(srcDir, entry.name);
|
|
12011
|
+
const destPath = import_path15.default.join(destDir, entry.name);
|
|
11530
12012
|
if (entry.isDirectory()) {
|
|
11531
12013
|
copyDirRecursive(srcPath, destPath);
|
|
11532
12014
|
} else if (entry.isFile()) {
|
|
11533
|
-
|
|
12015
|
+
import_fs13.default.copyFileSync(srcPath, destPath);
|
|
11534
12016
|
}
|
|
11535
12017
|
}
|
|
11536
12018
|
}
|
|
11537
12019
|
function copyStaticAssets(projectRoot, outDir) {
|
|
11538
|
-
const assetsSrc =
|
|
11539
|
-
const assetsDest =
|
|
12020
|
+
const assetsSrc = import_path15.default.join(projectRoot, "assets");
|
|
12021
|
+
const assetsDest = import_path15.default.join(outDir, "assets");
|
|
11540
12022
|
copyDirRecursive(assetsSrc, assetsDest);
|
|
11541
|
-
const publicDir =
|
|
12023
|
+
const publicDir = import_path15.default.join(projectRoot, "public");
|
|
11542
12024
|
const candidates = ["favicon.ico", "favicon.png"];
|
|
11543
12025
|
for (const name of candidates) {
|
|
11544
|
-
const fromPublic =
|
|
11545
|
-
if (
|
|
11546
|
-
const dest =
|
|
11547
|
-
ensureDir(
|
|
11548
|
-
|
|
12026
|
+
const fromPublic = import_path15.default.join(publicDir, name);
|
|
12027
|
+
if (import_fs13.default.existsSync(fromPublic)) {
|
|
12028
|
+
const dest = import_path15.default.join(outDir, name);
|
|
12029
|
+
ensureDir(import_path15.default.dirname(dest));
|
|
12030
|
+
import_fs13.default.copyFileSync(fromPublic, dest);
|
|
11549
12031
|
break;
|
|
11550
12032
|
}
|
|
11551
12033
|
}
|
|
@@ -11555,10 +12037,10 @@ function getFaviconInfo(projectRoot, staticDir = "public", isDev = false) {
|
|
|
11555
12037
|
{ name: "favicon.ico", type: "image/x-icon" },
|
|
11556
12038
|
{ name: "favicon.png", type: "image/png" }
|
|
11557
12039
|
];
|
|
11558
|
-
const publicDir =
|
|
12040
|
+
const publicDir = import_path15.default.join(projectRoot, staticDir);
|
|
11559
12041
|
for (const candidate of candidates) {
|
|
11560
|
-
const publicPath =
|
|
11561
|
-
if (
|
|
12042
|
+
const publicPath = import_path15.default.join(publicDir, candidate.name);
|
|
12043
|
+
if (import_fs13.default.existsSync(publicPath)) {
|
|
11562
12044
|
return {
|
|
11563
12045
|
path: `/${candidate.name}`,
|
|
11564
12046
|
// Served at root from public/
|
|
@@ -11576,10 +12058,10 @@ function generateAssetManifest(outDir, stats) {
|
|
|
11576
12058
|
},
|
|
11577
12059
|
chunks: {}
|
|
11578
12060
|
};
|
|
11579
|
-
if (!
|
|
12061
|
+
if (!import_fs13.default.existsSync(outDir)) {
|
|
11580
12062
|
return manifest;
|
|
11581
12063
|
}
|
|
11582
|
-
const files =
|
|
12064
|
+
const files = import_fs13.default.readdirSync(outDir);
|
|
11583
12065
|
if (stats) {
|
|
11584
12066
|
try {
|
|
11585
12067
|
const statsJson = stats.toJson({
|
|
@@ -11708,12 +12190,12 @@ function generateAssetManifest(outDir, stats) {
|
|
|
11708
12190
|
}
|
|
11709
12191
|
function loadAssetManifest(projectRoot) {
|
|
11710
12192
|
const { BUILD_FOLDER_NAME: BUILD_FOLDER_NAME2 } = (init_globals(), __toCommonJS(globals_exports));
|
|
11711
|
-
const manifestPath =
|
|
11712
|
-
if (!
|
|
12193
|
+
const manifestPath = import_path15.default.join(projectRoot, BUILD_FOLDER_NAME2, "asset-manifest.json");
|
|
12194
|
+
if (!import_fs13.default.existsSync(manifestPath)) {
|
|
11713
12195
|
return null;
|
|
11714
12196
|
}
|
|
11715
12197
|
try {
|
|
11716
|
-
const manifest = JSON.parse(
|
|
12198
|
+
const manifest = JSON.parse(import_fs13.default.readFileSync(manifestPath, "utf-8"));
|
|
11717
12199
|
return manifest;
|
|
11718
12200
|
} catch (err) {
|
|
11719
12201
|
return null;
|
|
@@ -11736,11 +12218,11 @@ function getClientCssPath(projectRoot) {
|
|
|
11736
12218
|
var import_dotenv = __toESM(require("dotenv"));
|
|
11737
12219
|
init_globals();
|
|
11738
12220
|
function createClientConfig(projectRoot, mode) {
|
|
11739
|
-
const buildDir =
|
|
11740
|
-
const clientEntry =
|
|
11741
|
-
const outDir =
|
|
11742
|
-
const envPath2 =
|
|
11743
|
-
if (
|
|
12221
|
+
const buildDir = import_path16.default.join(projectRoot, BUILD_FOLDER_NAME);
|
|
12222
|
+
const clientEntry = import_path16.default.join(buildDir, "boostrap.ts");
|
|
12223
|
+
const outDir = import_path16.default.join(buildDir, "client");
|
|
12224
|
+
const envPath2 = import_path16.default.join(projectRoot, ".env");
|
|
12225
|
+
if (import_fs14.default.existsSync(envPath2)) {
|
|
11744
12226
|
import_dotenv.default.config({ path: envPath2 });
|
|
11745
12227
|
}
|
|
11746
12228
|
const publicEnv = {};
|
|
@@ -11860,8 +12342,8 @@ function createClientConfig(projectRoot, mode) {
|
|
|
11860
12342
|
}
|
|
11861
12343
|
|
|
11862
12344
|
// modules/build/bundler/client.ts
|
|
11863
|
-
var
|
|
11864
|
-
var
|
|
12345
|
+
var import_path17 = __toESM(require("path"));
|
|
12346
|
+
var import_fs15 = __toESM(require("fs"));
|
|
11865
12347
|
init_globals();
|
|
11866
12348
|
function startClientBundler(projectRoot, mode = "development") {
|
|
11867
12349
|
const { config, outDir } = createClientConfig(projectRoot, mode);
|
|
@@ -11971,15 +12453,15 @@ function buildClientBundle(projectRoot) {
|
|
|
11971
12453
|
}
|
|
11972
12454
|
copyStaticAssets(projectRoot, outDir);
|
|
11973
12455
|
const assetManifest = generateAssetManifest(outDir, stats);
|
|
11974
|
-
const manifestPath =
|
|
11975
|
-
|
|
12456
|
+
const manifestPath = import_path17.default.join(projectRoot, BUILD_FOLDER_NAME, "asset-manifest.json");
|
|
12457
|
+
import_fs15.default.writeFileSync(manifestPath, JSON.stringify(assetManifest, null, 2), "utf-8");
|
|
11976
12458
|
resolve3({ outDir });
|
|
11977
12459
|
});
|
|
11978
12460
|
});
|
|
11979
12461
|
}
|
|
11980
12462
|
|
|
11981
12463
|
// ../../node_modules/.pnpm/chokidar@4.0.3/node_modules/chokidar/esm/index.js
|
|
11982
|
-
var
|
|
12464
|
+
var import_fs17 = require("fs");
|
|
11983
12465
|
var import_promises3 = require("fs/promises");
|
|
11984
12466
|
var import_events = require("events");
|
|
11985
12467
|
var sysPath2 = __toESM(require("path"), 1);
|
|
@@ -12054,7 +12536,7 @@ var ReaddirpStream = class extends import_node_stream.Readable {
|
|
|
12054
12536
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
12055
12537
|
const statMethod = opts.lstat ? import_promises.lstat : import_promises.stat;
|
|
12056
12538
|
if (wantBigintFsStats) {
|
|
12057
|
-
this._stat = (
|
|
12539
|
+
this._stat = (path30) => statMethod(path30, { bigint: true });
|
|
12058
12540
|
} else {
|
|
12059
12541
|
this._stat = statMethod;
|
|
12060
12542
|
}
|
|
@@ -12079,8 +12561,8 @@ var ReaddirpStream = class extends import_node_stream.Readable {
|
|
|
12079
12561
|
const par = this.parent;
|
|
12080
12562
|
const fil = par && par.files;
|
|
12081
12563
|
if (fil && fil.length > 0) {
|
|
12082
|
-
const { path:
|
|
12083
|
-
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent,
|
|
12564
|
+
const { path: path30, depth } = par;
|
|
12565
|
+
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path30));
|
|
12084
12566
|
const awaited = await Promise.all(slice);
|
|
12085
12567
|
for (const entry of awaited) {
|
|
12086
12568
|
if (!entry)
|
|
@@ -12120,20 +12602,20 @@ var ReaddirpStream = class extends import_node_stream.Readable {
|
|
|
12120
12602
|
this.reading = false;
|
|
12121
12603
|
}
|
|
12122
12604
|
}
|
|
12123
|
-
async _exploreDir(
|
|
12605
|
+
async _exploreDir(path30, depth) {
|
|
12124
12606
|
let files;
|
|
12125
12607
|
try {
|
|
12126
|
-
files = await (0, import_promises.readdir)(
|
|
12608
|
+
files = await (0, import_promises.readdir)(path30, this._rdOptions);
|
|
12127
12609
|
} catch (error) {
|
|
12128
12610
|
this._onError(error);
|
|
12129
12611
|
}
|
|
12130
|
-
return { files, depth, path:
|
|
12612
|
+
return { files, depth, path: path30 };
|
|
12131
12613
|
}
|
|
12132
|
-
async _formatEntry(dirent,
|
|
12614
|
+
async _formatEntry(dirent, path30) {
|
|
12133
12615
|
let entry;
|
|
12134
12616
|
const basename3 = this._isDirent ? dirent.name : dirent;
|
|
12135
12617
|
try {
|
|
12136
|
-
const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(
|
|
12618
|
+
const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path30, basename3));
|
|
12137
12619
|
entry = { path: (0, import_node_path.relative)(this._root, fullPath), fullPath, basename: basename3 };
|
|
12138
12620
|
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
12139
12621
|
} catch (err) {
|
|
@@ -12204,7 +12686,7 @@ function readdirp(root, options = {}) {
|
|
|
12204
12686
|
}
|
|
12205
12687
|
|
|
12206
12688
|
// ../../node_modules/.pnpm/chokidar@4.0.3/node_modules/chokidar/esm/handler.js
|
|
12207
|
-
var
|
|
12689
|
+
var import_fs16 = require("fs");
|
|
12208
12690
|
var import_promises2 = require("fs/promises");
|
|
12209
12691
|
var sysPath = __toESM(require("path"), 1);
|
|
12210
12692
|
var import_os = require("os");
|
|
@@ -12533,16 +13015,16 @@ var delFromSet = (main, prop, item) => {
|
|
|
12533
13015
|
};
|
|
12534
13016
|
var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
|
|
12535
13017
|
var FsWatchInstances = /* @__PURE__ */ new Map();
|
|
12536
|
-
function createFsWatchInstance(
|
|
13018
|
+
function createFsWatchInstance(path30, options, listener, errHandler, emitRaw) {
|
|
12537
13019
|
const handleEvent = (rawEvent, evPath) => {
|
|
12538
|
-
listener(
|
|
12539
|
-
emitRaw(rawEvent, evPath, { watchedPath:
|
|
12540
|
-
if (evPath &&
|
|
12541
|
-
fsWatchBroadcast(sysPath.resolve(
|
|
13020
|
+
listener(path30);
|
|
13021
|
+
emitRaw(rawEvent, evPath, { watchedPath: path30 });
|
|
13022
|
+
if (evPath && path30 !== evPath) {
|
|
13023
|
+
fsWatchBroadcast(sysPath.resolve(path30, evPath), KEY_LISTENERS, sysPath.join(path30, evPath));
|
|
12542
13024
|
}
|
|
12543
13025
|
};
|
|
12544
13026
|
try {
|
|
12545
|
-
return (0,
|
|
13027
|
+
return (0, import_fs16.watch)(path30, {
|
|
12546
13028
|
persistent: options.persistent
|
|
12547
13029
|
}, handleEvent);
|
|
12548
13030
|
} catch (error) {
|
|
@@ -12558,12 +13040,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
|
|
|
12558
13040
|
listener(val1, val2, val3);
|
|
12559
13041
|
});
|
|
12560
13042
|
};
|
|
12561
|
-
var setFsWatchListener = (
|
|
13043
|
+
var setFsWatchListener = (path30, fullPath, options, handlers) => {
|
|
12562
13044
|
const { listener, errHandler, rawEmitter } = handlers;
|
|
12563
13045
|
let cont = FsWatchInstances.get(fullPath);
|
|
12564
13046
|
let watcher;
|
|
12565
13047
|
if (!options.persistent) {
|
|
12566
|
-
watcher = createFsWatchInstance(
|
|
13048
|
+
watcher = createFsWatchInstance(path30, options, listener, errHandler, rawEmitter);
|
|
12567
13049
|
if (!watcher)
|
|
12568
13050
|
return;
|
|
12569
13051
|
return watcher.close.bind(watcher);
|
|
@@ -12574,7 +13056,7 @@ var setFsWatchListener = (path28, fullPath, options, handlers) => {
|
|
|
12574
13056
|
addAndConvert(cont, KEY_RAW, rawEmitter);
|
|
12575
13057
|
} else {
|
|
12576
13058
|
watcher = createFsWatchInstance(
|
|
12577
|
-
|
|
13059
|
+
path30,
|
|
12578
13060
|
options,
|
|
12579
13061
|
fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
|
|
12580
13062
|
errHandler,
|
|
@@ -12589,7 +13071,7 @@ var setFsWatchListener = (path28, fullPath, options, handlers) => {
|
|
|
12589
13071
|
cont.watcherUnusable = true;
|
|
12590
13072
|
if (isWindows && error.code === "EPERM") {
|
|
12591
13073
|
try {
|
|
12592
|
-
const fd = await (0, import_promises2.open)(
|
|
13074
|
+
const fd = await (0, import_promises2.open)(path30, "r");
|
|
12593
13075
|
await fd.close();
|
|
12594
13076
|
broadcastErr(error);
|
|
12595
13077
|
} catch (err) {
|
|
@@ -12620,12 +13102,12 @@ var setFsWatchListener = (path28, fullPath, options, handlers) => {
|
|
|
12620
13102
|
};
|
|
12621
13103
|
};
|
|
12622
13104
|
var FsWatchFileInstances = /* @__PURE__ */ new Map();
|
|
12623
|
-
var setFsWatchFileListener = (
|
|
13105
|
+
var setFsWatchFileListener = (path30, fullPath, options, handlers) => {
|
|
12624
13106
|
const { listener, rawEmitter } = handlers;
|
|
12625
13107
|
let cont = FsWatchFileInstances.get(fullPath);
|
|
12626
13108
|
const copts = cont && cont.options;
|
|
12627
13109
|
if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) {
|
|
12628
|
-
(0,
|
|
13110
|
+
(0, import_fs16.unwatchFile)(fullPath);
|
|
12629
13111
|
cont = void 0;
|
|
12630
13112
|
}
|
|
12631
13113
|
if (cont) {
|
|
@@ -12636,13 +13118,13 @@ var setFsWatchFileListener = (path28, fullPath, options, handlers) => {
|
|
|
12636
13118
|
listeners: listener,
|
|
12637
13119
|
rawEmitters: rawEmitter,
|
|
12638
13120
|
options,
|
|
12639
|
-
watcher: (0,
|
|
13121
|
+
watcher: (0, import_fs16.watchFile)(fullPath, options, (curr, prev) => {
|
|
12640
13122
|
foreach(cont.rawEmitters, (rawEmitter2) => {
|
|
12641
13123
|
rawEmitter2(EV.CHANGE, fullPath, { curr, prev });
|
|
12642
13124
|
});
|
|
12643
13125
|
const currmtime = curr.mtimeMs;
|
|
12644
13126
|
if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
|
|
12645
|
-
foreach(cont.listeners, (listener2) => listener2(
|
|
13127
|
+
foreach(cont.listeners, (listener2) => listener2(path30, curr));
|
|
12646
13128
|
}
|
|
12647
13129
|
})
|
|
12648
13130
|
};
|
|
@@ -12653,7 +13135,7 @@ var setFsWatchFileListener = (path28, fullPath, options, handlers) => {
|
|
|
12653
13135
|
delFromSet(cont, KEY_RAW, rawEmitter);
|
|
12654
13136
|
if (isEmptySet(cont.listeners)) {
|
|
12655
13137
|
FsWatchFileInstances.delete(fullPath);
|
|
12656
|
-
(0,
|
|
13138
|
+
(0, import_fs16.unwatchFile)(fullPath);
|
|
12657
13139
|
cont.options = cont.watcher = void 0;
|
|
12658
13140
|
Object.freeze(cont);
|
|
12659
13141
|
}
|
|
@@ -12670,13 +13152,13 @@ var NodeFsHandler = class {
|
|
|
12670
13152
|
* @param listener on fs change
|
|
12671
13153
|
* @returns closer for the watcher instance
|
|
12672
13154
|
*/
|
|
12673
|
-
_watchWithNodeFs(
|
|
13155
|
+
_watchWithNodeFs(path30, listener) {
|
|
12674
13156
|
const opts = this.fsw.options;
|
|
12675
|
-
const directory = sysPath.dirname(
|
|
12676
|
-
const basename3 = sysPath.basename(
|
|
13157
|
+
const directory = sysPath.dirname(path30);
|
|
13158
|
+
const basename3 = sysPath.basename(path30);
|
|
12677
13159
|
const parent = this.fsw._getWatchedDir(directory);
|
|
12678
13160
|
parent.add(basename3);
|
|
12679
|
-
const absolutePath = sysPath.resolve(
|
|
13161
|
+
const absolutePath = sysPath.resolve(path30);
|
|
12680
13162
|
const options = {
|
|
12681
13163
|
persistent: opts.persistent
|
|
12682
13164
|
};
|
|
@@ -12686,12 +13168,12 @@ var NodeFsHandler = class {
|
|
|
12686
13168
|
if (opts.usePolling) {
|
|
12687
13169
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
12688
13170
|
options.interval = enableBin && isBinaryPath(basename3) ? opts.binaryInterval : opts.interval;
|
|
12689
|
-
closer = setFsWatchFileListener(
|
|
13171
|
+
closer = setFsWatchFileListener(path30, absolutePath, options, {
|
|
12690
13172
|
listener,
|
|
12691
13173
|
rawEmitter: this.fsw._emitRaw
|
|
12692
13174
|
});
|
|
12693
13175
|
} else {
|
|
12694
|
-
closer = setFsWatchListener(
|
|
13176
|
+
closer = setFsWatchListener(path30, absolutePath, options, {
|
|
12695
13177
|
listener,
|
|
12696
13178
|
errHandler: this._boundHandleError,
|
|
12697
13179
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -12713,7 +13195,7 @@ var NodeFsHandler = class {
|
|
|
12713
13195
|
let prevStats = stats;
|
|
12714
13196
|
if (parent.has(basename3))
|
|
12715
13197
|
return;
|
|
12716
|
-
const listener = async (
|
|
13198
|
+
const listener = async (path30, newStats) => {
|
|
12717
13199
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
|
|
12718
13200
|
return;
|
|
12719
13201
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
@@ -12727,11 +13209,11 @@ var NodeFsHandler = class {
|
|
|
12727
13209
|
this.fsw._emit(EV.CHANGE, file, newStats2);
|
|
12728
13210
|
}
|
|
12729
13211
|
if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
|
|
12730
|
-
this.fsw._closeFile(
|
|
13212
|
+
this.fsw._closeFile(path30);
|
|
12731
13213
|
prevStats = newStats2;
|
|
12732
13214
|
const closer2 = this._watchWithNodeFs(file, listener);
|
|
12733
13215
|
if (closer2)
|
|
12734
|
-
this.fsw._addPathCloser(
|
|
13216
|
+
this.fsw._addPathCloser(path30, closer2);
|
|
12735
13217
|
} else {
|
|
12736
13218
|
prevStats = newStats2;
|
|
12737
13219
|
}
|
|
@@ -12763,7 +13245,7 @@ var NodeFsHandler = class {
|
|
|
12763
13245
|
* @param item basename of this item
|
|
12764
13246
|
* @returns true if no more processing is needed for this entry.
|
|
12765
13247
|
*/
|
|
12766
|
-
async _handleSymlink(entry, directory,
|
|
13248
|
+
async _handleSymlink(entry, directory, path30, item) {
|
|
12767
13249
|
if (this.fsw.closed) {
|
|
12768
13250
|
return;
|
|
12769
13251
|
}
|
|
@@ -12773,7 +13255,7 @@ var NodeFsHandler = class {
|
|
|
12773
13255
|
this.fsw._incrReadyCount();
|
|
12774
13256
|
let linkPath;
|
|
12775
13257
|
try {
|
|
12776
|
-
linkPath = await (0, import_promises2.realpath)(
|
|
13258
|
+
linkPath = await (0, import_promises2.realpath)(path30);
|
|
12777
13259
|
} catch (e) {
|
|
12778
13260
|
this.fsw._emitReady();
|
|
12779
13261
|
return true;
|
|
@@ -12783,12 +13265,12 @@ var NodeFsHandler = class {
|
|
|
12783
13265
|
if (dir.has(item)) {
|
|
12784
13266
|
if (this.fsw._symlinkPaths.get(full) !== linkPath) {
|
|
12785
13267
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
12786
|
-
this.fsw._emit(EV.CHANGE,
|
|
13268
|
+
this.fsw._emit(EV.CHANGE, path30, entry.stats);
|
|
12787
13269
|
}
|
|
12788
13270
|
} else {
|
|
12789
13271
|
dir.add(item);
|
|
12790
13272
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
12791
|
-
this.fsw._emit(EV.ADD,
|
|
13273
|
+
this.fsw._emit(EV.ADD, path30, entry.stats);
|
|
12792
13274
|
}
|
|
12793
13275
|
this.fsw._emitReady();
|
|
12794
13276
|
return true;
|
|
@@ -12817,9 +13299,9 @@ var NodeFsHandler = class {
|
|
|
12817
13299
|
return;
|
|
12818
13300
|
}
|
|
12819
13301
|
const item = entry.path;
|
|
12820
|
-
let
|
|
13302
|
+
let path30 = sysPath.join(directory, item);
|
|
12821
13303
|
current.add(item);
|
|
12822
|
-
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory,
|
|
13304
|
+
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path30, item)) {
|
|
12823
13305
|
return;
|
|
12824
13306
|
}
|
|
12825
13307
|
if (this.fsw.closed) {
|
|
@@ -12828,8 +13310,8 @@ var NodeFsHandler = class {
|
|
|
12828
13310
|
}
|
|
12829
13311
|
if (item === target || !target && !previous.has(item)) {
|
|
12830
13312
|
this.fsw._incrReadyCount();
|
|
12831
|
-
|
|
12832
|
-
this._addToNodeFs(
|
|
13313
|
+
path30 = sysPath.join(dir, sysPath.relative(dir, path30));
|
|
13314
|
+
this._addToNodeFs(path30, initialAdd, wh, depth + 1);
|
|
12833
13315
|
}
|
|
12834
13316
|
}).on(EV.ERROR, this._boundHandleError);
|
|
12835
13317
|
return new Promise((resolve3, reject) => {
|
|
@@ -12898,13 +13380,13 @@ var NodeFsHandler = class {
|
|
|
12898
13380
|
* @param depth Child path actually targeted for watch
|
|
12899
13381
|
* @param target Child path actually targeted for watch
|
|
12900
13382
|
*/
|
|
12901
|
-
async _addToNodeFs(
|
|
13383
|
+
async _addToNodeFs(path30, initialAdd, priorWh, depth, target) {
|
|
12902
13384
|
const ready = this.fsw._emitReady;
|
|
12903
|
-
if (this.fsw._isIgnored(
|
|
13385
|
+
if (this.fsw._isIgnored(path30) || this.fsw.closed) {
|
|
12904
13386
|
ready();
|
|
12905
13387
|
return false;
|
|
12906
13388
|
}
|
|
12907
|
-
const wh = this.fsw._getWatchHelpers(
|
|
13389
|
+
const wh = this.fsw._getWatchHelpers(path30);
|
|
12908
13390
|
if (priorWh) {
|
|
12909
13391
|
wh.filterPath = (entry) => priorWh.filterPath(entry);
|
|
12910
13392
|
wh.filterDir = (entry) => priorWh.filterDir(entry);
|
|
@@ -12920,8 +13402,8 @@ var NodeFsHandler = class {
|
|
|
12920
13402
|
const follow = this.fsw.options.followSymlinks;
|
|
12921
13403
|
let closer;
|
|
12922
13404
|
if (stats.isDirectory()) {
|
|
12923
|
-
const absPath = sysPath.resolve(
|
|
12924
|
-
const targetPath = follow ? await (0, import_promises2.realpath)(
|
|
13405
|
+
const absPath = sysPath.resolve(path30);
|
|
13406
|
+
const targetPath = follow ? await (0, import_promises2.realpath)(path30) : path30;
|
|
12925
13407
|
if (this.fsw.closed)
|
|
12926
13408
|
return;
|
|
12927
13409
|
closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
|
|
@@ -12931,29 +13413,29 @@ var NodeFsHandler = class {
|
|
|
12931
13413
|
this.fsw._symlinkPaths.set(absPath, targetPath);
|
|
12932
13414
|
}
|
|
12933
13415
|
} else if (stats.isSymbolicLink()) {
|
|
12934
|
-
const targetPath = follow ? await (0, import_promises2.realpath)(
|
|
13416
|
+
const targetPath = follow ? await (0, import_promises2.realpath)(path30) : path30;
|
|
12935
13417
|
if (this.fsw.closed)
|
|
12936
13418
|
return;
|
|
12937
13419
|
const parent = sysPath.dirname(wh.watchPath);
|
|
12938
13420
|
this.fsw._getWatchedDir(parent).add(wh.watchPath);
|
|
12939
13421
|
this.fsw._emit(EV.ADD, wh.watchPath, stats);
|
|
12940
|
-
closer = await this._handleDir(parent, stats, initialAdd, depth,
|
|
13422
|
+
closer = await this._handleDir(parent, stats, initialAdd, depth, path30, wh, targetPath);
|
|
12941
13423
|
if (this.fsw.closed)
|
|
12942
13424
|
return;
|
|
12943
13425
|
if (targetPath !== void 0) {
|
|
12944
|
-
this.fsw._symlinkPaths.set(sysPath.resolve(
|
|
13426
|
+
this.fsw._symlinkPaths.set(sysPath.resolve(path30), targetPath);
|
|
12945
13427
|
}
|
|
12946
13428
|
} else {
|
|
12947
13429
|
closer = this._handleFile(wh.watchPath, stats, initialAdd);
|
|
12948
13430
|
}
|
|
12949
13431
|
ready();
|
|
12950
13432
|
if (closer)
|
|
12951
|
-
this.fsw._addPathCloser(
|
|
13433
|
+
this.fsw._addPathCloser(path30, closer);
|
|
12952
13434
|
return false;
|
|
12953
13435
|
} catch (error) {
|
|
12954
13436
|
if (this.fsw._handleError(error)) {
|
|
12955
13437
|
ready();
|
|
12956
|
-
return
|
|
13438
|
+
return path30;
|
|
12957
13439
|
}
|
|
12958
13440
|
}
|
|
12959
13441
|
}
|
|
@@ -12996,26 +13478,26 @@ function createPattern(matcher) {
|
|
|
12996
13478
|
}
|
|
12997
13479
|
return () => false;
|
|
12998
13480
|
}
|
|
12999
|
-
function normalizePath(
|
|
13000
|
-
if (typeof
|
|
13481
|
+
function normalizePath(path30) {
|
|
13482
|
+
if (typeof path30 !== "string")
|
|
13001
13483
|
throw new Error("string expected");
|
|
13002
|
-
|
|
13003
|
-
|
|
13484
|
+
path30 = sysPath2.normalize(path30);
|
|
13485
|
+
path30 = path30.replace(/\\/g, "/");
|
|
13004
13486
|
let prepend = false;
|
|
13005
|
-
if (
|
|
13487
|
+
if (path30.startsWith("//"))
|
|
13006
13488
|
prepend = true;
|
|
13007
13489
|
const DOUBLE_SLASH_RE2 = /\/\//;
|
|
13008
|
-
while (
|
|
13009
|
-
|
|
13490
|
+
while (path30.match(DOUBLE_SLASH_RE2))
|
|
13491
|
+
path30 = path30.replace(DOUBLE_SLASH_RE2, "/");
|
|
13010
13492
|
if (prepend)
|
|
13011
|
-
|
|
13012
|
-
return
|
|
13493
|
+
path30 = "/" + path30;
|
|
13494
|
+
return path30;
|
|
13013
13495
|
}
|
|
13014
13496
|
function matchPatterns(patterns, testString, stats) {
|
|
13015
|
-
const
|
|
13497
|
+
const path30 = normalizePath(testString);
|
|
13016
13498
|
for (let index = 0; index < patterns.length; index++) {
|
|
13017
13499
|
const pattern = patterns[index];
|
|
13018
|
-
if (pattern(
|
|
13500
|
+
if (pattern(path30, stats)) {
|
|
13019
13501
|
return true;
|
|
13020
13502
|
}
|
|
13021
13503
|
}
|
|
@@ -13055,19 +13537,19 @@ var toUnix = (string) => {
|
|
|
13055
13537
|
}
|
|
13056
13538
|
return str;
|
|
13057
13539
|
};
|
|
13058
|
-
var normalizePathToUnix = (
|
|
13059
|
-
var normalizeIgnored = (cwd = "") => (
|
|
13060
|
-
if (typeof
|
|
13061
|
-
return normalizePathToUnix(sysPath2.isAbsolute(
|
|
13540
|
+
var normalizePathToUnix = (path30) => toUnix(sysPath2.normalize(toUnix(path30)));
|
|
13541
|
+
var normalizeIgnored = (cwd = "") => (path30) => {
|
|
13542
|
+
if (typeof path30 === "string") {
|
|
13543
|
+
return normalizePathToUnix(sysPath2.isAbsolute(path30) ? path30 : sysPath2.join(cwd, path30));
|
|
13062
13544
|
} else {
|
|
13063
|
-
return
|
|
13545
|
+
return path30;
|
|
13064
13546
|
}
|
|
13065
13547
|
};
|
|
13066
|
-
var getAbsolutePath = (
|
|
13067
|
-
if (sysPath2.isAbsolute(
|
|
13068
|
-
return
|
|
13548
|
+
var getAbsolutePath = (path30, cwd) => {
|
|
13549
|
+
if (sysPath2.isAbsolute(path30)) {
|
|
13550
|
+
return path30;
|
|
13069
13551
|
}
|
|
13070
|
-
return sysPath2.join(cwd,
|
|
13552
|
+
return sysPath2.join(cwd, path30);
|
|
13071
13553
|
};
|
|
13072
13554
|
var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
|
|
13073
13555
|
var DirEntry = class {
|
|
@@ -13122,10 +13604,10 @@ var DirEntry = class {
|
|
|
13122
13604
|
var STAT_METHOD_F = "stat";
|
|
13123
13605
|
var STAT_METHOD_L = "lstat";
|
|
13124
13606
|
var WatchHelper = class {
|
|
13125
|
-
constructor(
|
|
13607
|
+
constructor(path30, follow, fsw) {
|
|
13126
13608
|
this.fsw = fsw;
|
|
13127
|
-
const watchPath =
|
|
13128
|
-
this.path =
|
|
13609
|
+
const watchPath = path30;
|
|
13610
|
+
this.path = path30 = path30.replace(REPLACER_RE, "");
|
|
13129
13611
|
this.watchPath = watchPath;
|
|
13130
13612
|
this.fullWatchPath = sysPath2.resolve(watchPath);
|
|
13131
13613
|
this.dirParts = [];
|
|
@@ -13247,20 +13729,20 @@ var FSWatcher = class extends import_events.EventEmitter {
|
|
|
13247
13729
|
this._closePromise = void 0;
|
|
13248
13730
|
let paths = unifyPaths(paths_);
|
|
13249
13731
|
if (cwd) {
|
|
13250
|
-
paths = paths.map((
|
|
13251
|
-
const absPath = getAbsolutePath(
|
|
13732
|
+
paths = paths.map((path30) => {
|
|
13733
|
+
const absPath = getAbsolutePath(path30, cwd);
|
|
13252
13734
|
return absPath;
|
|
13253
13735
|
});
|
|
13254
13736
|
}
|
|
13255
|
-
paths.forEach((
|
|
13256
|
-
this._removeIgnoredPath(
|
|
13737
|
+
paths.forEach((path30) => {
|
|
13738
|
+
this._removeIgnoredPath(path30);
|
|
13257
13739
|
});
|
|
13258
13740
|
this._userIgnored = void 0;
|
|
13259
13741
|
if (!this._readyCount)
|
|
13260
13742
|
this._readyCount = 0;
|
|
13261
13743
|
this._readyCount += paths.length;
|
|
13262
|
-
Promise.all(paths.map(async (
|
|
13263
|
-
const res = await this._nodeFsHandler._addToNodeFs(
|
|
13744
|
+
Promise.all(paths.map(async (path30) => {
|
|
13745
|
+
const res = await this._nodeFsHandler._addToNodeFs(path30, !_internal, void 0, 0, _origAdd);
|
|
13264
13746
|
if (res)
|
|
13265
13747
|
this._emitReady();
|
|
13266
13748
|
return res;
|
|
@@ -13282,17 +13764,17 @@ var FSWatcher = class extends import_events.EventEmitter {
|
|
|
13282
13764
|
return this;
|
|
13283
13765
|
const paths = unifyPaths(paths_);
|
|
13284
13766
|
const { cwd } = this.options;
|
|
13285
|
-
paths.forEach((
|
|
13286
|
-
if (!sysPath2.isAbsolute(
|
|
13767
|
+
paths.forEach((path30) => {
|
|
13768
|
+
if (!sysPath2.isAbsolute(path30) && !this._closers.has(path30)) {
|
|
13287
13769
|
if (cwd)
|
|
13288
|
-
|
|
13289
|
-
|
|
13770
|
+
path30 = sysPath2.join(cwd, path30);
|
|
13771
|
+
path30 = sysPath2.resolve(path30);
|
|
13290
13772
|
}
|
|
13291
|
-
this._closePath(
|
|
13292
|
-
this._addIgnoredPath(
|
|
13293
|
-
if (this._watched.has(
|
|
13773
|
+
this._closePath(path30);
|
|
13774
|
+
this._addIgnoredPath(path30);
|
|
13775
|
+
if (this._watched.has(path30)) {
|
|
13294
13776
|
this._addIgnoredPath({
|
|
13295
|
-
path:
|
|
13777
|
+
path: path30,
|
|
13296
13778
|
recursive: true
|
|
13297
13779
|
});
|
|
13298
13780
|
}
|
|
@@ -13356,38 +13838,38 @@ var FSWatcher = class extends import_events.EventEmitter {
|
|
|
13356
13838
|
* @param stats arguments to be passed with event
|
|
13357
13839
|
* @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
|
|
13358
13840
|
*/
|
|
13359
|
-
async _emit(event,
|
|
13841
|
+
async _emit(event, path30, stats) {
|
|
13360
13842
|
if (this.closed)
|
|
13361
13843
|
return;
|
|
13362
13844
|
const opts = this.options;
|
|
13363
13845
|
if (isWindows)
|
|
13364
|
-
|
|
13846
|
+
path30 = sysPath2.normalize(path30);
|
|
13365
13847
|
if (opts.cwd)
|
|
13366
|
-
|
|
13367
|
-
const args = [
|
|
13848
|
+
path30 = sysPath2.relative(opts.cwd, path30);
|
|
13849
|
+
const args = [path30];
|
|
13368
13850
|
if (stats != null)
|
|
13369
13851
|
args.push(stats);
|
|
13370
13852
|
const awf = opts.awaitWriteFinish;
|
|
13371
13853
|
let pw;
|
|
13372
|
-
if (awf && (pw = this._pendingWrites.get(
|
|
13854
|
+
if (awf && (pw = this._pendingWrites.get(path30))) {
|
|
13373
13855
|
pw.lastChange = /* @__PURE__ */ new Date();
|
|
13374
13856
|
return this;
|
|
13375
13857
|
}
|
|
13376
13858
|
if (opts.atomic) {
|
|
13377
13859
|
if (event === EVENTS.UNLINK) {
|
|
13378
|
-
this._pendingUnlinks.set(
|
|
13860
|
+
this._pendingUnlinks.set(path30, [event, ...args]);
|
|
13379
13861
|
setTimeout(() => {
|
|
13380
|
-
this._pendingUnlinks.forEach((entry,
|
|
13862
|
+
this._pendingUnlinks.forEach((entry, path31) => {
|
|
13381
13863
|
this.emit(...entry);
|
|
13382
13864
|
this.emit(EVENTS.ALL, ...entry);
|
|
13383
|
-
this._pendingUnlinks.delete(
|
|
13865
|
+
this._pendingUnlinks.delete(path31);
|
|
13384
13866
|
});
|
|
13385
13867
|
}, typeof opts.atomic === "number" ? opts.atomic : 100);
|
|
13386
13868
|
return this;
|
|
13387
13869
|
}
|
|
13388
|
-
if (event === EVENTS.ADD && this._pendingUnlinks.has(
|
|
13870
|
+
if (event === EVENTS.ADD && this._pendingUnlinks.has(path30)) {
|
|
13389
13871
|
event = EVENTS.CHANGE;
|
|
13390
|
-
this._pendingUnlinks.delete(
|
|
13872
|
+
this._pendingUnlinks.delete(path30);
|
|
13391
13873
|
}
|
|
13392
13874
|
}
|
|
13393
13875
|
if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
|
|
@@ -13405,16 +13887,16 @@ var FSWatcher = class extends import_events.EventEmitter {
|
|
|
13405
13887
|
this.emitWithAll(event, args);
|
|
13406
13888
|
}
|
|
13407
13889
|
};
|
|
13408
|
-
this._awaitWriteFinish(
|
|
13890
|
+
this._awaitWriteFinish(path30, awf.stabilityThreshold, event, awfEmit);
|
|
13409
13891
|
return this;
|
|
13410
13892
|
}
|
|
13411
13893
|
if (event === EVENTS.CHANGE) {
|
|
13412
|
-
const isThrottled = !this._throttle(EVENTS.CHANGE,
|
|
13894
|
+
const isThrottled = !this._throttle(EVENTS.CHANGE, path30, 50);
|
|
13413
13895
|
if (isThrottled)
|
|
13414
13896
|
return this;
|
|
13415
13897
|
}
|
|
13416
13898
|
if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
|
|
13417
|
-
const fullPath = opts.cwd ? sysPath2.join(opts.cwd,
|
|
13899
|
+
const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path30) : path30;
|
|
13418
13900
|
let stats2;
|
|
13419
13901
|
try {
|
|
13420
13902
|
stats2 = await (0, import_promises3.stat)(fullPath);
|
|
@@ -13445,23 +13927,23 @@ var FSWatcher = class extends import_events.EventEmitter {
|
|
|
13445
13927
|
* @param timeout duration of time to suppress duplicate actions
|
|
13446
13928
|
* @returns tracking object or false if action should be suppressed
|
|
13447
13929
|
*/
|
|
13448
|
-
_throttle(actionType,
|
|
13930
|
+
_throttle(actionType, path30, timeout) {
|
|
13449
13931
|
if (!this._throttled.has(actionType)) {
|
|
13450
13932
|
this._throttled.set(actionType, /* @__PURE__ */ new Map());
|
|
13451
13933
|
}
|
|
13452
13934
|
const action = this._throttled.get(actionType);
|
|
13453
13935
|
if (!action)
|
|
13454
13936
|
throw new Error("invalid throttle");
|
|
13455
|
-
const actionPath = action.get(
|
|
13937
|
+
const actionPath = action.get(path30);
|
|
13456
13938
|
if (actionPath) {
|
|
13457
13939
|
actionPath.count++;
|
|
13458
13940
|
return false;
|
|
13459
13941
|
}
|
|
13460
13942
|
let timeoutObject;
|
|
13461
13943
|
const clear = () => {
|
|
13462
|
-
const item = action.get(
|
|
13944
|
+
const item = action.get(path30);
|
|
13463
13945
|
const count = item ? item.count : 0;
|
|
13464
|
-
action.delete(
|
|
13946
|
+
action.delete(path30);
|
|
13465
13947
|
clearTimeout(timeoutObject);
|
|
13466
13948
|
if (item)
|
|
13467
13949
|
clearTimeout(item.timeoutObject);
|
|
@@ -13469,7 +13951,7 @@ var FSWatcher = class extends import_events.EventEmitter {
|
|
|
13469
13951
|
};
|
|
13470
13952
|
timeoutObject = setTimeout(clear, timeout);
|
|
13471
13953
|
const thr = { timeoutObject, clear, count: 0 };
|
|
13472
|
-
action.set(
|
|
13954
|
+
action.set(path30, thr);
|
|
13473
13955
|
return thr;
|
|
13474
13956
|
}
|
|
13475
13957
|
_incrReadyCount() {
|
|
@@ -13483,44 +13965,44 @@ var FSWatcher = class extends import_events.EventEmitter {
|
|
|
13483
13965
|
* @param event
|
|
13484
13966
|
* @param awfEmit Callback to be called when ready for event to be emitted.
|
|
13485
13967
|
*/
|
|
13486
|
-
_awaitWriteFinish(
|
|
13968
|
+
_awaitWriteFinish(path30, threshold, event, awfEmit) {
|
|
13487
13969
|
const awf = this.options.awaitWriteFinish;
|
|
13488
13970
|
if (typeof awf !== "object")
|
|
13489
13971
|
return;
|
|
13490
13972
|
const pollInterval = awf.pollInterval;
|
|
13491
13973
|
let timeoutHandler;
|
|
13492
|
-
let fullPath =
|
|
13493
|
-
if (this.options.cwd && !sysPath2.isAbsolute(
|
|
13494
|
-
fullPath = sysPath2.join(this.options.cwd,
|
|
13974
|
+
let fullPath = path30;
|
|
13975
|
+
if (this.options.cwd && !sysPath2.isAbsolute(path30)) {
|
|
13976
|
+
fullPath = sysPath2.join(this.options.cwd, path30);
|
|
13495
13977
|
}
|
|
13496
13978
|
const now = /* @__PURE__ */ new Date();
|
|
13497
13979
|
const writes = this._pendingWrites;
|
|
13498
13980
|
function awaitWriteFinishFn(prevStat) {
|
|
13499
|
-
(0,
|
|
13500
|
-
if (err || !writes.has(
|
|
13981
|
+
(0, import_fs17.stat)(fullPath, (err, curStat) => {
|
|
13982
|
+
if (err || !writes.has(path30)) {
|
|
13501
13983
|
if (err && err.code !== "ENOENT")
|
|
13502
13984
|
awfEmit(err);
|
|
13503
13985
|
return;
|
|
13504
13986
|
}
|
|
13505
13987
|
const now2 = Number(/* @__PURE__ */ new Date());
|
|
13506
13988
|
if (prevStat && curStat.size !== prevStat.size) {
|
|
13507
|
-
writes.get(
|
|
13989
|
+
writes.get(path30).lastChange = now2;
|
|
13508
13990
|
}
|
|
13509
|
-
const pw = writes.get(
|
|
13991
|
+
const pw = writes.get(path30);
|
|
13510
13992
|
const df = now2 - pw.lastChange;
|
|
13511
13993
|
if (df >= threshold) {
|
|
13512
|
-
writes.delete(
|
|
13994
|
+
writes.delete(path30);
|
|
13513
13995
|
awfEmit(void 0, curStat);
|
|
13514
13996
|
} else {
|
|
13515
13997
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
|
|
13516
13998
|
}
|
|
13517
13999
|
});
|
|
13518
14000
|
}
|
|
13519
|
-
if (!writes.has(
|
|
13520
|
-
writes.set(
|
|
14001
|
+
if (!writes.has(path30)) {
|
|
14002
|
+
writes.set(path30, {
|
|
13521
14003
|
lastChange: now,
|
|
13522
14004
|
cancelWait: () => {
|
|
13523
|
-
writes.delete(
|
|
14005
|
+
writes.delete(path30);
|
|
13524
14006
|
clearTimeout(timeoutHandler);
|
|
13525
14007
|
return event;
|
|
13526
14008
|
}
|
|
@@ -13531,8 +14013,8 @@ var FSWatcher = class extends import_events.EventEmitter {
|
|
|
13531
14013
|
/**
|
|
13532
14014
|
* Determines whether user has asked to ignore this path.
|
|
13533
14015
|
*/
|
|
13534
|
-
_isIgnored(
|
|
13535
|
-
if (this.options.atomic && DOT_RE.test(
|
|
14016
|
+
_isIgnored(path30, stats) {
|
|
14017
|
+
if (this.options.atomic && DOT_RE.test(path30))
|
|
13536
14018
|
return true;
|
|
13537
14019
|
if (!this._userIgnored) {
|
|
13538
14020
|
const { cwd } = this.options;
|
|
@@ -13542,17 +14024,17 @@ var FSWatcher = class extends import_events.EventEmitter {
|
|
|
13542
14024
|
const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
|
|
13543
14025
|
this._userIgnored = anymatch(list, void 0);
|
|
13544
14026
|
}
|
|
13545
|
-
return this._userIgnored(
|
|
14027
|
+
return this._userIgnored(path30, stats);
|
|
13546
14028
|
}
|
|
13547
|
-
_isntIgnored(
|
|
13548
|
-
return !this._isIgnored(
|
|
14029
|
+
_isntIgnored(path30, stat4) {
|
|
14030
|
+
return !this._isIgnored(path30, stat4);
|
|
13549
14031
|
}
|
|
13550
14032
|
/**
|
|
13551
14033
|
* Provides a set of common helpers and properties relating to symlink handling.
|
|
13552
14034
|
* @param path file or directory pattern being watched
|
|
13553
14035
|
*/
|
|
13554
|
-
_getWatchHelpers(
|
|
13555
|
-
return new WatchHelper(
|
|
14036
|
+
_getWatchHelpers(path30) {
|
|
14037
|
+
return new WatchHelper(path30, this.options.followSymlinks, this);
|
|
13556
14038
|
}
|
|
13557
14039
|
// Directory helpers
|
|
13558
14040
|
// -----------------
|
|
@@ -13584,63 +14066,63 @@ var FSWatcher = class extends import_events.EventEmitter {
|
|
|
13584
14066
|
* @param item base path of item/directory
|
|
13585
14067
|
*/
|
|
13586
14068
|
_remove(directory, item, isDirectory) {
|
|
13587
|
-
const
|
|
13588
|
-
const fullPath = sysPath2.resolve(
|
|
13589
|
-
isDirectory = isDirectory != null ? isDirectory : this._watched.has(
|
|
13590
|
-
if (!this._throttle("remove",
|
|
14069
|
+
const path30 = sysPath2.join(directory, item);
|
|
14070
|
+
const fullPath = sysPath2.resolve(path30);
|
|
14071
|
+
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path30) || this._watched.has(fullPath);
|
|
14072
|
+
if (!this._throttle("remove", path30, 100))
|
|
13591
14073
|
return;
|
|
13592
14074
|
if (!isDirectory && this._watched.size === 1) {
|
|
13593
14075
|
this.add(directory, item, true);
|
|
13594
14076
|
}
|
|
13595
|
-
const wp = this._getWatchedDir(
|
|
14077
|
+
const wp = this._getWatchedDir(path30);
|
|
13596
14078
|
const nestedDirectoryChildren = wp.getChildren();
|
|
13597
|
-
nestedDirectoryChildren.forEach((nested) => this._remove(
|
|
14079
|
+
nestedDirectoryChildren.forEach((nested) => this._remove(path30, nested));
|
|
13598
14080
|
const parent = this._getWatchedDir(directory);
|
|
13599
14081
|
const wasTracked = parent.has(item);
|
|
13600
14082
|
parent.remove(item);
|
|
13601
14083
|
if (this._symlinkPaths.has(fullPath)) {
|
|
13602
14084
|
this._symlinkPaths.delete(fullPath);
|
|
13603
14085
|
}
|
|
13604
|
-
let relPath =
|
|
14086
|
+
let relPath = path30;
|
|
13605
14087
|
if (this.options.cwd)
|
|
13606
|
-
relPath = sysPath2.relative(this.options.cwd,
|
|
14088
|
+
relPath = sysPath2.relative(this.options.cwd, path30);
|
|
13607
14089
|
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
13608
14090
|
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
13609
14091
|
if (event === EVENTS.ADD)
|
|
13610
14092
|
return;
|
|
13611
14093
|
}
|
|
13612
|
-
this._watched.delete(
|
|
14094
|
+
this._watched.delete(path30);
|
|
13613
14095
|
this._watched.delete(fullPath);
|
|
13614
14096
|
const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
|
|
13615
|
-
if (wasTracked && !this._isIgnored(
|
|
13616
|
-
this._emit(eventName,
|
|
13617
|
-
this._closePath(
|
|
14097
|
+
if (wasTracked && !this._isIgnored(path30))
|
|
14098
|
+
this._emit(eventName, path30);
|
|
14099
|
+
this._closePath(path30);
|
|
13618
14100
|
}
|
|
13619
14101
|
/**
|
|
13620
14102
|
* Closes all watchers for a path
|
|
13621
14103
|
*/
|
|
13622
|
-
_closePath(
|
|
13623
|
-
this._closeFile(
|
|
13624
|
-
const dir = sysPath2.dirname(
|
|
13625
|
-
this._getWatchedDir(dir).remove(sysPath2.basename(
|
|
14104
|
+
_closePath(path30) {
|
|
14105
|
+
this._closeFile(path30);
|
|
14106
|
+
const dir = sysPath2.dirname(path30);
|
|
14107
|
+
this._getWatchedDir(dir).remove(sysPath2.basename(path30));
|
|
13626
14108
|
}
|
|
13627
14109
|
/**
|
|
13628
14110
|
* Closes only file-specific watchers
|
|
13629
14111
|
*/
|
|
13630
|
-
_closeFile(
|
|
13631
|
-
const closers = this._closers.get(
|
|
14112
|
+
_closeFile(path30) {
|
|
14113
|
+
const closers = this._closers.get(path30);
|
|
13632
14114
|
if (!closers)
|
|
13633
14115
|
return;
|
|
13634
14116
|
closers.forEach((closer) => closer());
|
|
13635
|
-
this._closers.delete(
|
|
14117
|
+
this._closers.delete(path30);
|
|
13636
14118
|
}
|
|
13637
|
-
_addPathCloser(
|
|
14119
|
+
_addPathCloser(path30, closer) {
|
|
13638
14120
|
if (!closer)
|
|
13639
14121
|
return;
|
|
13640
|
-
let list = this._closers.get(
|
|
14122
|
+
let list = this._closers.get(path30);
|
|
13641
14123
|
if (!list) {
|
|
13642
14124
|
list = [];
|
|
13643
|
-
this._closers.set(
|
|
14125
|
+
this._closers.set(path30, list);
|
|
13644
14126
|
}
|
|
13645
14127
|
list.push(closer);
|
|
13646
14128
|
}
|
|
@@ -13670,7 +14152,7 @@ function watch(paths, options = {}) {
|
|
|
13670
14152
|
var esm_default = { watch, FSWatcher };
|
|
13671
14153
|
|
|
13672
14154
|
// modules/dev/hot-reload-client/index.ts
|
|
13673
|
-
var
|
|
14155
|
+
var import_path18 = __toESM(require("path"));
|
|
13674
14156
|
init_globals();
|
|
13675
14157
|
function setupHotReload({
|
|
13676
14158
|
app,
|
|
@@ -13712,7 +14194,7 @@ function setupHotReload({
|
|
|
13712
14194
|
});
|
|
13713
14195
|
});
|
|
13714
14196
|
console.log(`[hot-reload-server] \u2705 SSE endpoint registered at ${route}`);
|
|
13715
|
-
const resolvedProjectRoot = projectRoot ?
|
|
14197
|
+
const resolvedProjectRoot = projectRoot ? import_path18.default.resolve(projectRoot) : import_path18.default.dirname(import_path18.default.resolve(appDir));
|
|
13716
14198
|
const watcher = esm_default.watch(resolvedProjectRoot, {
|
|
13717
14199
|
ignoreInitial: true,
|
|
13718
14200
|
ignored: [
|
|
@@ -13752,11 +14234,11 @@ function setupHotReload({
|
|
|
13752
14234
|
let broadcastTimeout = null;
|
|
13753
14235
|
const BROADCAST_DEBOUNCE_MS = 300;
|
|
13754
14236
|
async function broadcastReload(reason, filePath) {
|
|
13755
|
-
const normalizedPath =
|
|
14237
|
+
const normalizedPath = import_path18.default.normalize(filePath);
|
|
13756
14238
|
if (normalizedPath.includes(BUILD_FOLDER_NAME) || normalizedPath.includes(".loly") || normalizedPath.endsWith(".map") || normalizedPath.endsWith(".log") || normalizedPath.includes("route-chunks.json") || normalizedPath.includes("routes-client.ts") || normalizedPath.includes("/client/route-")) {
|
|
13757
14239
|
return;
|
|
13758
14240
|
}
|
|
13759
|
-
const rel =
|
|
14241
|
+
const rel = import_path18.default.relative(appDir, filePath);
|
|
13760
14242
|
console.log(`[hot-reload] ${reason}: ${rel}`);
|
|
13761
14243
|
if (broadcastTimeout) {
|
|
13762
14244
|
clearTimeout(broadcastTimeout);
|
|
@@ -13806,9 +14288,9 @@ data: reload:${rel}
|
|
|
13806
14288
|
}
|
|
13807
14289
|
|
|
13808
14290
|
// modules/dev/hot-reload-server/index.ts
|
|
13809
|
-
var
|
|
14291
|
+
var import_path19 = __toESM(require("path"));
|
|
13810
14292
|
function clearAppRequireCache(appDir) {
|
|
13811
|
-
const appDirNormalized =
|
|
14293
|
+
const appDirNormalized = import_path19.default.resolve(appDir);
|
|
13812
14294
|
for (const id of Object.keys(require.cache)) {
|
|
13813
14295
|
if (id.startsWith(appDirNormalized)) {
|
|
13814
14296
|
delete require.cache[id];
|
|
@@ -13820,8 +14302,8 @@ function clearAppRequireCache(appDir) {
|
|
|
13820
14302
|
init_globals();
|
|
13821
14303
|
|
|
13822
14304
|
// src/config.ts
|
|
13823
|
-
var
|
|
13824
|
-
var
|
|
14305
|
+
var import_path20 = __toESM(require("path"));
|
|
14306
|
+
var import_fs18 = __toESM(require("fs"));
|
|
13825
14307
|
init_globals();
|
|
13826
14308
|
var DEFAULT_CONFIG = {
|
|
13827
14309
|
directories: {
|
|
@@ -13888,8 +14370,8 @@ function validateConfig(config, projectRoot) {
|
|
|
13888
14370
|
if (!config.directories.app || typeof config.directories.app !== "string") {
|
|
13889
14371
|
errors.push("config.directories.app must be a non-empty string");
|
|
13890
14372
|
} else {
|
|
13891
|
-
const appDir =
|
|
13892
|
-
if (!
|
|
14373
|
+
const appDir = import_path20.default.join(projectRoot, config.directories.app);
|
|
14374
|
+
if (!import_fs18.default.existsSync(appDir) && process.env.NODE_ENV !== "test") {
|
|
13893
14375
|
errors.push(
|
|
13894
14376
|
`App directory not found: ${config.directories.app}
|
|
13895
14377
|
Expected at: ${appDir}
|
|
@@ -13993,17 +14475,17 @@ function validateConfig(config, projectRoot) {
|
|
|
13993
14475
|
}
|
|
13994
14476
|
function loadConfig(projectRoot) {
|
|
13995
14477
|
const configFiles = [
|
|
13996
|
-
|
|
13997
|
-
|
|
13998
|
-
|
|
14478
|
+
import_path20.default.join(projectRoot, "loly.config.ts"),
|
|
14479
|
+
import_path20.default.join(projectRoot, "loly.config.js"),
|
|
14480
|
+
import_path20.default.join(projectRoot, "loly.config.json")
|
|
13999
14481
|
];
|
|
14000
14482
|
let userConfig = {};
|
|
14001
14483
|
let loadedConfigFile = null;
|
|
14002
14484
|
for (const configFile of configFiles) {
|
|
14003
|
-
if (
|
|
14485
|
+
if (import_fs18.default.existsSync(configFile)) {
|
|
14004
14486
|
try {
|
|
14005
14487
|
if (configFile.endsWith(".json")) {
|
|
14006
|
-
const content =
|
|
14488
|
+
const content = import_fs18.default.readFileSync(configFile, "utf-8");
|
|
14007
14489
|
userConfig = JSON.parse(content);
|
|
14008
14490
|
} else {
|
|
14009
14491
|
if (process.env.NODE_ENV === "development") {
|
|
@@ -14012,12 +14494,12 @@ function loadConfig(projectRoot) {
|
|
|
14012
14494
|
const mod = require(configFile);
|
|
14013
14495
|
userConfig = typeof mod.default === "function" ? mod.default(process.env.NODE_ENV) : mod.default || mod.config || mod;
|
|
14014
14496
|
}
|
|
14015
|
-
loadedConfigFile =
|
|
14497
|
+
loadedConfigFile = import_path20.default.relative(projectRoot, configFile);
|
|
14016
14498
|
break;
|
|
14017
14499
|
} catch (error) {
|
|
14018
14500
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
14019
14501
|
throw new ConfigValidationError(
|
|
14020
|
-
`Failed to load configuration from ${
|
|
14502
|
+
`Failed to load configuration from ${import_path20.default.relative(projectRoot, configFile)}:
|
|
14021
14503
|
${errorMessage}
|
|
14022
14504
|
\u{1F4A1} Suggestion: Check that your config file exports a valid configuration object`
|
|
14023
14505
|
);
|
|
@@ -14041,20 +14523,20 @@ ${error.message}`;
|
|
|
14041
14523
|
return config;
|
|
14042
14524
|
}
|
|
14043
14525
|
function getAppDir(projectRoot, config) {
|
|
14044
|
-
return
|
|
14526
|
+
return import_path20.default.resolve(projectRoot, config.directories.app);
|
|
14045
14527
|
}
|
|
14046
14528
|
function getBuildDir(projectRoot, config) {
|
|
14047
|
-
return
|
|
14529
|
+
return import_path20.default.join(projectRoot, config.directories.build);
|
|
14048
14530
|
}
|
|
14049
14531
|
function getStaticDir(projectRoot, config) {
|
|
14050
|
-
return
|
|
14532
|
+
return import_path20.default.resolve(projectRoot, config.directories.static);
|
|
14051
14533
|
}
|
|
14052
14534
|
|
|
14053
14535
|
// modules/server/setup.ts
|
|
14054
14536
|
function setupStaticFiles(app, projectRoot, config) {
|
|
14055
14537
|
if (!config) return;
|
|
14056
14538
|
const staticDir = getStaticDir(projectRoot, config);
|
|
14057
|
-
if (
|
|
14539
|
+
if (import_fs19.default.existsSync(staticDir)) {
|
|
14058
14540
|
app.use(
|
|
14059
14541
|
import_express.default.static(staticDir, {
|
|
14060
14542
|
// In production, add caching headers for better performance
|
|
@@ -14080,7 +14562,7 @@ function setupServer(app, options) {
|
|
|
14080
14562
|
var getRoutes = getRoutes2;
|
|
14081
14563
|
const { outDir, waitForBuild } = startClientBundler(projectRoot, "development");
|
|
14082
14564
|
const onFileChange = async (filePath) => {
|
|
14083
|
-
const rel =
|
|
14565
|
+
const rel = import_path21.default.relative(appDir, filePath);
|
|
14084
14566
|
const isPageFile = filePath.includes("page.tsx") || filePath.includes("page.ts") || filePath.includes("layout.tsx") || filePath.includes("layout.ts") || filePath.includes("_not-found") || filePath.includes("_error");
|
|
14085
14567
|
const isTsFile = filePath.endsWith(".ts") || filePath.endsWith(".tsx");
|
|
14086
14568
|
if (isTsFile) {
|
|
@@ -14116,8 +14598,8 @@ function setupServer(app, options) {
|
|
|
14116
14598
|
const wssRoutes = routeLoader.loadWssRoutes();
|
|
14117
14599
|
const notFoundPage = routeLoader.loadNotFoundRoute();
|
|
14118
14600
|
const errorPage = routeLoader.loadErrorRoute();
|
|
14119
|
-
const buildDir = config ? getBuildDir(projectRoot, config) :
|
|
14120
|
-
const clientOutDir =
|
|
14601
|
+
const buildDir = config ? getBuildDir(projectRoot, config) : import_path21.default.join(projectRoot, BUILD_FOLDER_NAME);
|
|
14602
|
+
const clientOutDir = import_path21.default.join(buildDir, "client");
|
|
14121
14603
|
app.use(
|
|
14122
14604
|
"/static",
|
|
14123
14605
|
import_express.default.static(clientOutDir, {
|
|
@@ -14326,12 +14808,12 @@ var DEFAULT_IGNORED_PATHS = [
|
|
|
14326
14808
|
/^\/sockjs-node/
|
|
14327
14809
|
// Hot reload websocket
|
|
14328
14810
|
];
|
|
14329
|
-
function shouldIgnorePath(
|
|
14811
|
+
function shouldIgnorePath(path30, ignoredPaths) {
|
|
14330
14812
|
return ignoredPaths.some((pattern) => {
|
|
14331
14813
|
if (typeof pattern === "string") {
|
|
14332
|
-
return
|
|
14814
|
+
return path30 === pattern || path30.startsWith(pattern);
|
|
14333
14815
|
}
|
|
14334
|
-
return pattern.test(
|
|
14816
|
+
return pattern.test(path30);
|
|
14335
14817
|
});
|
|
14336
14818
|
}
|
|
14337
14819
|
function requestLoggerMiddleware(options = {}) {
|
|
@@ -14490,11 +14972,11 @@ function createStrictRateLimiterFromConfig(config) {
|
|
|
14490
14972
|
}
|
|
14491
14973
|
|
|
14492
14974
|
// modules/server/middleware/auto-rate-limit.ts
|
|
14493
|
-
function matchesStrictPattern(
|
|
14975
|
+
function matchesStrictPattern(path30, patterns) {
|
|
14494
14976
|
for (const pattern of patterns) {
|
|
14495
14977
|
const regexPattern = pattern.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*").replace(/\//g, "\\/");
|
|
14496
14978
|
const regex = new RegExp(`^${regexPattern}$`);
|
|
14497
|
-
if (regex.test(
|
|
14979
|
+
if (regex.test(path30)) {
|
|
14498
14980
|
return true;
|
|
14499
14981
|
}
|
|
14500
14982
|
}
|
|
@@ -14529,8 +15011,31 @@ function getAutoRateLimiter(route, strictPatterns = [], rateLimitConfig) {
|
|
|
14529
15011
|
|
|
14530
15012
|
// modules/server/handlers/api.ts
|
|
14531
15013
|
async function handleApiRequest(options) {
|
|
14532
|
-
const { apiRoutes, urlPath, req, res, env = "dev" } = options;
|
|
14533
|
-
|
|
15014
|
+
const { apiRoutes, urlPath, req, res, env = "dev", rewriteLoader } = options;
|
|
15015
|
+
let finalUrlPath = urlPath;
|
|
15016
|
+
let extractedParams = {};
|
|
15017
|
+
if (rewriteLoader) {
|
|
15018
|
+
try {
|
|
15019
|
+
const compiledRewrites = await rewriteLoader.loadRewrites();
|
|
15020
|
+
const rewriteResult = await processRewrites(urlPath, compiledRewrites, req);
|
|
15021
|
+
if (rewriteResult) {
|
|
15022
|
+
finalUrlPath = rewriteResult.rewrittenPath;
|
|
15023
|
+
extractedParams = rewriteResult.extractedParams;
|
|
15024
|
+
Object.assign(req.query, extractedParams);
|
|
15025
|
+
if (!req.locals) {
|
|
15026
|
+
req.locals = {};
|
|
15027
|
+
}
|
|
15028
|
+
Object.assign(req.locals, extractedParams);
|
|
15029
|
+
}
|
|
15030
|
+
} catch (error) {
|
|
15031
|
+
const reqLogger = getRequestLogger(req);
|
|
15032
|
+
reqLogger.error("Error processing rewrites", error, {
|
|
15033
|
+
urlPath
|
|
15034
|
+
});
|
|
15035
|
+
}
|
|
15036
|
+
}
|
|
15037
|
+
finalUrlPath = finalUrlPath.replace(/\/$/, "") || "/";
|
|
15038
|
+
const matched = matchApiRoute(apiRoutes, finalUrlPath);
|
|
14534
15039
|
if (!matched) {
|
|
14535
15040
|
res.status(404).json({ error: "Not Found" });
|
|
14536
15041
|
return;
|
|
@@ -14551,9 +15056,13 @@ async function handleApiRequest(options) {
|
|
|
14551
15056
|
Response: (body = {}, status = 200) => res.status(status).json(body),
|
|
14552
15057
|
NotFound: (body = {}) => res.status(404).json(body),
|
|
14553
15058
|
params: sanitizedParams,
|
|
14554
|
-
pathname:
|
|
15059
|
+
pathname: finalUrlPath,
|
|
15060
|
+
// Use rewritten path
|
|
14555
15061
|
locals: {}
|
|
14556
15062
|
};
|
|
15063
|
+
if (extractedParams && Object.keys(extractedParams).length > 0) {
|
|
15064
|
+
Object.assign(ctx.locals, extractedParams);
|
|
15065
|
+
}
|
|
14557
15066
|
req.query = sanitizedQuery;
|
|
14558
15067
|
try {
|
|
14559
15068
|
const autoRateLimiter = getAutoRateLimiter(
|
|
@@ -15047,7 +15556,7 @@ var buildRouterData = (req) => {
|
|
|
15047
15556
|
};
|
|
15048
15557
|
|
|
15049
15558
|
// modules/server/handlers/middleware.ts
|
|
15050
|
-
var
|
|
15559
|
+
var import_path22 = __toESM(require("path"));
|
|
15051
15560
|
async function runRouteMiddlewares(route, ctx) {
|
|
15052
15561
|
for (let i = 0; i < route.middlewares.length; i++) {
|
|
15053
15562
|
const mw = route.middlewares[i];
|
|
@@ -15058,7 +15567,7 @@ async function runRouteMiddlewares(route, ctx) {
|
|
|
15058
15567
|
);
|
|
15059
15568
|
} catch (error) {
|
|
15060
15569
|
const reqLogger = getRequestLogger(ctx.req);
|
|
15061
|
-
const relativePath = route.pageFile ?
|
|
15570
|
+
const relativePath = route.pageFile ? import_path22.default.relative(process.cwd(), route.pageFile) : route.pattern;
|
|
15062
15571
|
reqLogger.error("Route middleware failed", error instanceof Error ? error : new Error(String(error)), {
|
|
15063
15572
|
route: route.pattern,
|
|
15064
15573
|
middlewareIndex: i,
|
|
@@ -15073,7 +15582,7 @@ async function runRouteMiddlewares(route, ctx) {
|
|
|
15073
15582
|
}
|
|
15074
15583
|
|
|
15075
15584
|
// modules/server/handlers/server-hook.ts
|
|
15076
|
-
var
|
|
15585
|
+
var import_path23 = __toESM(require("path"));
|
|
15077
15586
|
function createServerHookErrorMessage(error, hookType, routePattern, filePath) {
|
|
15078
15587
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
15079
15588
|
const errorStack = error instanceof Error ? error.stack : void 0;
|
|
@@ -15082,7 +15591,7 @@ function createServerHookErrorMessage(error, hookType, routePattern, filePath) {
|
|
|
15082
15591
|
message += `Route: ${routePattern}
|
|
15083
15592
|
`;
|
|
15084
15593
|
if (filePath) {
|
|
15085
|
-
const relativePath =
|
|
15594
|
+
const relativePath = import_path23.default.relative(process.cwd(), filePath);
|
|
15086
15595
|
message += `File: ${relativePath}
|
|
15087
15596
|
`;
|
|
15088
15597
|
}
|
|
@@ -15143,7 +15652,9 @@ function handleDataResponse(res, loaderResult, theme, layoutProps, pageProps, er
|
|
|
15143
15652
|
// Combined props for backward compatibility
|
|
15144
15653
|
props: loaderResult.props ?? {},
|
|
15145
15654
|
metadata: loaderResult.metadata ?? null,
|
|
15146
|
-
theme: loaderResult.theme ?? theme ?? null
|
|
15655
|
+
theme: loaderResult.theme ?? theme ?? null,
|
|
15656
|
+
// Include pathname if provided (for rewrites - client needs to know the rewritten path)
|
|
15657
|
+
...loaderResult.pathname ? { pathname: loaderResult.pathname } : {}
|
|
15147
15658
|
};
|
|
15148
15659
|
if (layoutProps !== void 0 && layoutProps !== null) {
|
|
15149
15660
|
response.layoutProps = layoutProps;
|
|
@@ -15175,24 +15686,24 @@ function handleNotFound(res, urlPath) {
|
|
|
15175
15686
|
}
|
|
15176
15687
|
|
|
15177
15688
|
// modules/server/handlers/ssg.ts
|
|
15178
|
-
var
|
|
15179
|
-
var
|
|
15689
|
+
var import_fs20 = __toESM(require("fs"));
|
|
15690
|
+
var import_path24 = __toESM(require("path"));
|
|
15180
15691
|
var logger3 = createModuleLogger("ssg");
|
|
15181
15692
|
function getSsgDirForPath(baseDir, urlPath) {
|
|
15182
15693
|
const clean = urlPath === "/" ? "" : urlPath.replace(/^\/+/, "");
|
|
15183
|
-
return
|
|
15694
|
+
return import_path24.default.join(baseDir, clean);
|
|
15184
15695
|
}
|
|
15185
15696
|
function getSsgHtmlPath(baseDir, urlPath) {
|
|
15186
15697
|
const dir = getSsgDirForPath(baseDir, urlPath);
|
|
15187
|
-
return
|
|
15698
|
+
return import_path24.default.join(dir, "index.html");
|
|
15188
15699
|
}
|
|
15189
15700
|
function getSsgDataPath(baseDir, urlPath) {
|
|
15190
15701
|
const dir = getSsgDirForPath(baseDir, urlPath);
|
|
15191
|
-
return
|
|
15702
|
+
return import_path24.default.join(dir, "data.json");
|
|
15192
15703
|
}
|
|
15193
15704
|
function tryServeSsgHtml(res, ssgOutDir, urlPath) {
|
|
15194
15705
|
const ssgHtmlPath = getSsgHtmlPath(ssgOutDir, urlPath);
|
|
15195
|
-
if (!
|
|
15706
|
+
if (!import_fs20.default.existsSync(ssgHtmlPath)) {
|
|
15196
15707
|
return false;
|
|
15197
15708
|
}
|
|
15198
15709
|
logger3.info("Serving SSG HTML", { urlPath, ssgHtmlPath });
|
|
@@ -15202,17 +15713,17 @@ function tryServeSsgHtml(res, ssgOutDir, urlPath) {
|
|
|
15202
15713
|
);
|
|
15203
15714
|
res.statusCode = 200;
|
|
15204
15715
|
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
15205
|
-
const stream =
|
|
15716
|
+
const stream = import_fs20.default.createReadStream(ssgHtmlPath, { encoding: "utf-8" });
|
|
15206
15717
|
stream.pipe(res);
|
|
15207
15718
|
return true;
|
|
15208
15719
|
}
|
|
15209
15720
|
function tryServeSsgData(res, ssgOutDir, urlPath) {
|
|
15210
15721
|
const ssgDataPath = getSsgDataPath(ssgOutDir, urlPath);
|
|
15211
|
-
if (!
|
|
15722
|
+
if (!import_fs20.default.existsSync(ssgDataPath)) {
|
|
15212
15723
|
return false;
|
|
15213
15724
|
}
|
|
15214
15725
|
try {
|
|
15215
|
-
const raw =
|
|
15726
|
+
const raw = import_fs20.default.readFileSync(ssgDataPath, "utf-8");
|
|
15216
15727
|
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
15217
15728
|
res.status(200).end(raw);
|
|
15218
15729
|
return true;
|
|
@@ -15224,7 +15735,7 @@ function tryServeSsgData(res, ssgOutDir, urlPath) {
|
|
|
15224
15735
|
|
|
15225
15736
|
// modules/server/handlers/pages.ts
|
|
15226
15737
|
init_globals();
|
|
15227
|
-
var
|
|
15738
|
+
var import_path25 = __toESM(require("path"));
|
|
15228
15739
|
function mergeMetadata(base, override) {
|
|
15229
15740
|
if (!base && !override) return null;
|
|
15230
15741
|
if (!base) return override;
|
|
@@ -15291,8 +15802,43 @@ async function handlePageRequestInternal(options) {
|
|
|
15291
15802
|
ssgOutDir,
|
|
15292
15803
|
theme,
|
|
15293
15804
|
projectRoot,
|
|
15294
|
-
config
|
|
15805
|
+
config,
|
|
15806
|
+
rewriteLoader
|
|
15295
15807
|
} = options;
|
|
15808
|
+
let finalUrlPath = urlPath;
|
|
15809
|
+
let extractedParams = {};
|
|
15810
|
+
if (rewriteLoader) {
|
|
15811
|
+
try {
|
|
15812
|
+
const compiledRewrites = await rewriteLoader.loadRewrites();
|
|
15813
|
+
const rewriteResult = await processRewrites(urlPath, compiledRewrites, req);
|
|
15814
|
+
if (rewriteResult) {
|
|
15815
|
+
finalUrlPath = rewriteResult.rewrittenPath;
|
|
15816
|
+
extractedParams = rewriteResult.extractedParams;
|
|
15817
|
+
finalUrlPath = finalUrlPath.replace(/\/+/g, "/").replace(/^([^/])/, "/$1").replace(/\/$/, "") || "/";
|
|
15818
|
+
if (env === "dev") {
|
|
15819
|
+
const reqLogger2 = getRequestLogger(req);
|
|
15820
|
+
reqLogger2.debug("Rewrite applied", {
|
|
15821
|
+
originalPath: urlPath,
|
|
15822
|
+
rewrittenPath: finalUrlPath,
|
|
15823
|
+
extractedParams,
|
|
15824
|
+
host: req.get("host")
|
|
15825
|
+
});
|
|
15826
|
+
}
|
|
15827
|
+
Object.assign(req.query, extractedParams);
|
|
15828
|
+
if (!req.locals) {
|
|
15829
|
+
req.locals = {};
|
|
15830
|
+
}
|
|
15831
|
+
Object.assign(req.locals, extractedParams);
|
|
15832
|
+
}
|
|
15833
|
+
} catch (error) {
|
|
15834
|
+
const reqLogger2 = getRequestLogger(req);
|
|
15835
|
+
reqLogger2.error("Error processing rewrites", error, {
|
|
15836
|
+
urlPath,
|
|
15837
|
+
host: req.get("host")
|
|
15838
|
+
});
|
|
15839
|
+
}
|
|
15840
|
+
}
|
|
15841
|
+
finalUrlPath = finalUrlPath.replace(/\/$/, "") || "/";
|
|
15296
15842
|
const clientJsPath = env === "dev" ? "/static/client.js" : projectRoot ? getClientJsPath(projectRoot) : "/static/client.js";
|
|
15297
15843
|
const clientCssPath = env === "dev" ? "/static/client.css" : projectRoot ? getClientCssPath(projectRoot) : "/static/client.css";
|
|
15298
15844
|
const assetManifest = env === "prod" && projectRoot ? loadAssetManifest(projectRoot) : null;
|
|
@@ -15301,18 +15847,43 @@ async function handlePageRequestInternal(options) {
|
|
|
15301
15847
|
const skipLayoutHooks = isDataReq && req.headers["x-skip-layout-hooks"] === "true";
|
|
15302
15848
|
if (env === "prod" && ssgOutDir) {
|
|
15303
15849
|
if (isDataReq) {
|
|
15304
|
-
if (tryServeSsgData(res, ssgOutDir,
|
|
15850
|
+
if (tryServeSsgData(res, ssgOutDir, finalUrlPath)) {
|
|
15305
15851
|
return;
|
|
15306
15852
|
}
|
|
15307
15853
|
} else {
|
|
15308
|
-
if (tryServeSsgHtml(res, ssgOutDir,
|
|
15854
|
+
if (tryServeSsgHtml(res, ssgOutDir, finalUrlPath)) {
|
|
15309
15855
|
return;
|
|
15310
15856
|
}
|
|
15311
15857
|
}
|
|
15312
15858
|
}
|
|
15313
|
-
const matched = matchRoute(routes,
|
|
15859
|
+
const matched = matchRoute(routes, finalUrlPath);
|
|
15860
|
+
if (env === "dev") {
|
|
15861
|
+
const reqLogger2 = getRequestLogger(req);
|
|
15862
|
+
if (finalUrlPath !== urlPath) {
|
|
15863
|
+
reqLogger2.debug("Route matching after rewrite", {
|
|
15864
|
+
originalPath: urlPath,
|
|
15865
|
+
rewrittenPath: finalUrlPath,
|
|
15866
|
+
matched: !!matched,
|
|
15867
|
+
matchedRoute: matched?.route.pattern,
|
|
15868
|
+
matchedParams: matched?.params,
|
|
15869
|
+
availableRoutes: routes.slice(0, 10).map((r) => r.pattern)
|
|
15870
|
+
// Show first 10 routes
|
|
15871
|
+
});
|
|
15872
|
+
} else if (!matched) {
|
|
15873
|
+
reqLogger2.debug("No route match found", {
|
|
15874
|
+
path: finalUrlPath,
|
|
15875
|
+
availableRoutes: routes.slice(0, 10).map((r) => r.pattern)
|
|
15876
|
+
});
|
|
15877
|
+
}
|
|
15878
|
+
}
|
|
15314
15879
|
const routerData = buildRouterData(req);
|
|
15315
15880
|
if (!matched) {
|
|
15881
|
+
if (isDataReq) {
|
|
15882
|
+
res.statusCode = 404;
|
|
15883
|
+
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
15884
|
+
res.end(JSON.stringify({ notFound: true, pathname: finalUrlPath }));
|
|
15885
|
+
return;
|
|
15886
|
+
}
|
|
15316
15887
|
if (notFoundPage) {
|
|
15317
15888
|
const ctx2 = {
|
|
15318
15889
|
req,
|
|
@@ -15336,7 +15907,7 @@ async function handlePageRequestInternal(options) {
|
|
|
15336
15907
|
} catch (error) {
|
|
15337
15908
|
const reqLogger2 = getRequestLogger(req);
|
|
15338
15909
|
const layoutFile = notFoundPage.layoutFiles[i];
|
|
15339
|
-
const relativeLayoutPath = layoutFile ?
|
|
15910
|
+
const relativeLayoutPath = layoutFile ? import_path25.default.relative(projectRoot || process.cwd(), layoutFile) : "unknown";
|
|
15340
15911
|
reqLogger2.error("Layout middleware failed for not-found page", error instanceof Error ? error : new Error(String(error)), {
|
|
15341
15912
|
layoutIndex: i,
|
|
15342
15913
|
layoutFile: relativeLayoutPath
|
|
@@ -15357,7 +15928,7 @@ async function handlePageRequestInternal(options) {
|
|
|
15357
15928
|
} catch (error) {
|
|
15358
15929
|
const reqLogger2 = getRequestLogger(req);
|
|
15359
15930
|
const layoutFile = notFoundPage.layoutFiles[i];
|
|
15360
|
-
const relativeLayoutPath = layoutFile ?
|
|
15931
|
+
const relativeLayoutPath = layoutFile ? import_path25.default.relative(projectRoot || process.cwd(), layoutFile) : "unknown";
|
|
15361
15932
|
reqLogger2.warn("Layout server hook failed for not-found page", {
|
|
15362
15933
|
error: error instanceof Error ? error.message : String(error),
|
|
15363
15934
|
stack: error instanceof Error ? error.stack : void 0,
|
|
@@ -15391,7 +15962,7 @@ async function handlePageRequestInternal(options) {
|
|
|
15391
15962
|
);
|
|
15392
15963
|
return;
|
|
15393
15964
|
}
|
|
15394
|
-
const initialData2 = buildInitialData(
|
|
15965
|
+
const initialData2 = buildInitialData(finalUrlPath, {}, combinedLoaderResult2);
|
|
15395
15966
|
const appTree2 = buildAppTree(notFoundPage, {}, initialData2.props);
|
|
15396
15967
|
initialData2.notFound = true;
|
|
15397
15968
|
const nonce2 = res.locals.nonce || void 0;
|
|
@@ -15477,7 +16048,7 @@ async function handlePageRequestInternal(options) {
|
|
|
15477
16048
|
);
|
|
15478
16049
|
} catch (error) {
|
|
15479
16050
|
const layoutFile = route.layoutFiles[i];
|
|
15480
|
-
const relativeLayoutPath = layoutFile ?
|
|
16051
|
+
const relativeLayoutPath = layoutFile ? import_path25.default.relative(projectRoot || process.cwd(), layoutFile) : "unknown";
|
|
15481
16052
|
reqLogger.error("Layout middleware failed", error instanceof Error ? error : new Error(String(error)), {
|
|
15482
16053
|
route: route.pattern,
|
|
15483
16054
|
layoutIndex: i,
|
|
@@ -15501,7 +16072,7 @@ async function handlePageRequestInternal(options) {
|
|
|
15501
16072
|
}
|
|
15502
16073
|
} catch (error) {
|
|
15503
16074
|
const layoutFile = route.layoutFiles[i];
|
|
15504
|
-
const relativeLayoutPath = layoutFile ?
|
|
16075
|
+
const relativeLayoutPath = layoutFile ? import_path25.default.relative(projectRoot || process.cwd(), layoutFile) : "unknown";
|
|
15505
16076
|
reqLogger.warn("Layout server hook failed", {
|
|
15506
16077
|
error: error instanceof Error ? error.message : String(error),
|
|
15507
16078
|
stack: error instanceof Error ? error.stack : void 0,
|
|
@@ -15521,7 +16092,7 @@ async function handlePageRequestInternal(options) {
|
|
|
15521
16092
|
loaderResult.theme = theme;
|
|
15522
16093
|
}
|
|
15523
16094
|
} catch (error) {
|
|
15524
|
-
const relativePagePath = route.pageFile ?
|
|
16095
|
+
const relativePagePath = route.pageFile ? import_path25.default.relative(projectRoot || process.cwd(), route.pageFile) : "unknown";
|
|
15525
16096
|
reqLogger.error("Page server hook failed", {
|
|
15526
16097
|
error: error instanceof Error ? error.message : String(error),
|
|
15527
16098
|
stack: error instanceof Error ? error.stack : void 0,
|
|
@@ -15568,7 +16139,9 @@ async function handlePageRequestInternal(options) {
|
|
|
15568
16139
|
const combinedLoaderResult = {
|
|
15569
16140
|
...loaderResult,
|
|
15570
16141
|
props: combinedProps,
|
|
15571
|
-
metadata: combinedMetadata
|
|
16142
|
+
metadata: combinedMetadata,
|
|
16143
|
+
pathname: finalUrlPath
|
|
16144
|
+
// Include rewritten pathname for client-side matching
|
|
15572
16145
|
};
|
|
15573
16146
|
if (isDataReq) {
|
|
15574
16147
|
const pagePropsOnly = loaderResult.props || {};
|
|
@@ -15593,7 +16166,7 @@ async function handlePageRequestInternal(options) {
|
|
|
15593
16166
|
}
|
|
15594
16167
|
return;
|
|
15595
16168
|
}
|
|
15596
|
-
const initialData = buildInitialData(
|
|
16169
|
+
const initialData = buildInitialData(finalUrlPath, params, combinedLoaderResult);
|
|
15597
16170
|
const appTree = buildAppTree(route, params, initialData.props);
|
|
15598
16171
|
const chunkName = routeChunks[route.pattern];
|
|
15599
16172
|
let chunkHref = null;
|
|
@@ -15698,7 +16271,7 @@ async function renderErrorPageWithStream(errorPage, req, res, error, routeChunks
|
|
|
15698
16271
|
);
|
|
15699
16272
|
} catch (error2) {
|
|
15700
16273
|
const layoutFile = errorPage.layoutFiles[i];
|
|
15701
|
-
const relativeLayoutPath = layoutFile ?
|
|
16274
|
+
const relativeLayoutPath = layoutFile ? import_path25.default.relative(projectRoot || process.cwd(), layoutFile) : "unknown";
|
|
15702
16275
|
reqLogger.error("Layout middleware failed for error page", error2 instanceof Error ? error2 : new Error(String(error2)), {
|
|
15703
16276
|
layoutIndex: i,
|
|
15704
16277
|
layoutFile: relativeLayoutPath
|
|
@@ -15718,7 +16291,7 @@ async function renderErrorPageWithStream(errorPage, req, res, error, routeChunks
|
|
|
15718
16291
|
}
|
|
15719
16292
|
} catch (err) {
|
|
15720
16293
|
const layoutFile = errorPage.layoutFiles[i];
|
|
15721
|
-
const relativeLayoutPath = layoutFile ?
|
|
16294
|
+
const relativeLayoutPath = layoutFile ? import_path25.default.relative(projectRoot || process.cwd(), layoutFile) : "unknown";
|
|
15722
16295
|
reqLogger.warn("Layout server hook failed for error page", {
|
|
15723
16296
|
error: err instanceof Error ? err.message : String(err),
|
|
15724
16297
|
stack: err instanceof Error ? err.stack : void 0,
|
|
@@ -15994,7 +16567,19 @@ function validateRealtimeConfig(config) {
|
|
|
15994
16567
|
}
|
|
15995
16568
|
|
|
15996
16569
|
// modules/server/routes.ts
|
|
15997
|
-
var
|
|
16570
|
+
var import_path26 = __toESM(require("path"));
|
|
16571
|
+
var cachedRewriteLoader = null;
|
|
16572
|
+
var cachedProjectRoot = null;
|
|
16573
|
+
var cachedIsDev = null;
|
|
16574
|
+
function getRewriteLoader(projectRoot, isDev) {
|
|
16575
|
+
if (cachedRewriteLoader && cachedProjectRoot === projectRoot && cachedIsDev === isDev) {
|
|
16576
|
+
return cachedRewriteLoader;
|
|
16577
|
+
}
|
|
16578
|
+
cachedRewriteLoader = createRewriteLoader(projectRoot, isDev);
|
|
16579
|
+
cachedProjectRoot = projectRoot;
|
|
16580
|
+
cachedIsDev = isDev;
|
|
16581
|
+
return cachedRewriteLoader;
|
|
16582
|
+
}
|
|
15998
16583
|
function setupRoutes(options) {
|
|
15999
16584
|
const {
|
|
16000
16585
|
app,
|
|
@@ -16009,8 +16594,9 @@ function setupRoutes(options) {
|
|
|
16009
16594
|
config
|
|
16010
16595
|
} = options;
|
|
16011
16596
|
const routeChunks = routeLoader.loadRouteChunks();
|
|
16012
|
-
const
|
|
16013
|
-
|
|
16597
|
+
const rewriteLoader = getRewriteLoader(projectRoot, isDev);
|
|
16598
|
+
const ssgOutDir = import_path26.default.join(
|
|
16599
|
+
config ? getBuildDir(projectRoot, config) : import_path26.default.join(projectRoot, BUILD_FOLDER_NAME),
|
|
16014
16600
|
"ssg"
|
|
16015
16601
|
);
|
|
16016
16602
|
app.all("/api/*", async (req, res) => {
|
|
@@ -16025,7 +16611,8 @@ function setupRoutes(options) {
|
|
|
16025
16611
|
res,
|
|
16026
16612
|
env: isDev ? "dev" : "prod",
|
|
16027
16613
|
strictRateLimitPatterns: strictPatterns,
|
|
16028
|
-
rateLimitConfig
|
|
16614
|
+
rateLimitConfig,
|
|
16615
|
+
rewriteLoader
|
|
16029
16616
|
});
|
|
16030
16617
|
});
|
|
16031
16618
|
app.get("*", async (req, res) => {
|
|
@@ -16048,7 +16635,8 @@ function setupRoutes(options) {
|
|
|
16048
16635
|
ssgOutDir,
|
|
16049
16636
|
theme: req.cookies?.theme || "light",
|
|
16050
16637
|
projectRoot,
|
|
16051
|
-
config
|
|
16638
|
+
config,
|
|
16639
|
+
rewriteLoader
|
|
16052
16640
|
});
|
|
16053
16641
|
});
|
|
16054
16642
|
}
|
|
@@ -17237,8 +17825,8 @@ var setupApplication = async ({
|
|
|
17237
17825
|
|
|
17238
17826
|
// src/server.ts
|
|
17239
17827
|
var import_dotenv2 = __toESM(require("dotenv"));
|
|
17240
|
-
var envPath =
|
|
17241
|
-
if (
|
|
17828
|
+
var envPath = import_path27.default.join(process.cwd(), ".env");
|
|
17829
|
+
if (import_fs21.default.existsSync(envPath)) {
|
|
17242
17830
|
import_dotenv2.default.config({ path: envPath });
|
|
17243
17831
|
} else {
|
|
17244
17832
|
import_dotenv2.default.config();
|
|
@@ -17259,8 +17847,8 @@ async function startServer(options = {}) {
|
|
|
17259
17847
|
}
|
|
17260
17848
|
const port = options.port ?? (process.env.PORT ? parseInt(process.env.PORT, 10) : void 0) ?? config.server.port;
|
|
17261
17849
|
const host = process.env.HOST ?? (!isDev ? "0.0.0.0" : void 0) ?? config.server.host;
|
|
17262
|
-
const appDir = options.appDir ?? (isDev ? getAppDir(projectRoot, config) :
|
|
17263
|
-
if (!isDev && !
|
|
17850
|
+
const appDir = options.appDir ?? (isDev ? getAppDir(projectRoot, config) : import_path27.default.join(getBuildDir(projectRoot, config), "server"));
|
|
17851
|
+
if (!isDev && !import_fs21.default.existsSync(appDir)) {
|
|
17264
17852
|
logger4.error("Compiled directory not found", void 0, {
|
|
17265
17853
|
buildDir: config.directories.build,
|
|
17266
17854
|
appDir,
|
|
@@ -17331,10 +17919,10 @@ async function startProdServer(options = {}) {
|
|
|
17331
17919
|
}
|
|
17332
17920
|
|
|
17333
17921
|
// modules/build/ssg/builder.ts
|
|
17334
|
-
var
|
|
17922
|
+
var import_path31 = __toESM(require("path"));
|
|
17335
17923
|
|
|
17336
17924
|
// modules/build/ssg/path.ts
|
|
17337
|
-
var
|
|
17925
|
+
var import_path28 = __toESM(require("path"));
|
|
17338
17926
|
function buildPathFromPattern(pattern, params) {
|
|
17339
17927
|
const segments = pattern.split("/").filter(Boolean);
|
|
17340
17928
|
const parts = [];
|
|
@@ -17363,12 +17951,12 @@ function buildPathFromPattern(pattern, params) {
|
|
|
17363
17951
|
}
|
|
17364
17952
|
function pathToOutDir(baseDir, urlPath) {
|
|
17365
17953
|
const clean = urlPath === "/" ? "" : urlPath.replace(/^\/+/, "");
|
|
17366
|
-
return
|
|
17954
|
+
return import_path28.default.join(baseDir, clean);
|
|
17367
17955
|
}
|
|
17368
17956
|
|
|
17369
17957
|
// modules/build/ssg/renderer.ts
|
|
17370
|
-
var
|
|
17371
|
-
var
|
|
17958
|
+
var import_fs22 = __toESM(require("fs"));
|
|
17959
|
+
var import_path29 = __toESM(require("path"));
|
|
17372
17960
|
var import_server3 = require("react-dom/server");
|
|
17373
17961
|
init_globals();
|
|
17374
17962
|
async function renderStaticRoute(projectRoot, ssgOutDir, route, urlPath, params, config) {
|
|
@@ -17492,16 +18080,16 @@ async function renderStaticRoute(projectRoot, ssgOutDir, route, urlPath, params,
|
|
|
17492
18080
|
const html = "<!DOCTYPE html>" + (0, import_server3.renderToString)(documentTree);
|
|
17493
18081
|
const dir = pathToOutDir(ssgOutDir, urlPath);
|
|
17494
18082
|
ensureDir(dir);
|
|
17495
|
-
const htmlFile =
|
|
17496
|
-
const dataFile =
|
|
17497
|
-
|
|
17498
|
-
|
|
18083
|
+
const htmlFile = import_path29.default.join(dir, "index.html");
|
|
18084
|
+
const dataFile = import_path29.default.join(dir, "data.json");
|
|
18085
|
+
import_fs22.default.writeFileSync(htmlFile, html, "utf-8");
|
|
18086
|
+
import_fs22.default.writeFileSync(dataFile, JSON.stringify(initialData, null, 2), "utf-8");
|
|
17499
18087
|
}
|
|
17500
18088
|
|
|
17501
18089
|
// modules/build/ssg/builder.ts
|
|
17502
18090
|
init_globals();
|
|
17503
18091
|
async function buildStaticPages(projectRoot, routes, config) {
|
|
17504
|
-
const ssgOutDir =
|
|
18092
|
+
const ssgOutDir = import_path31.default.join(projectRoot, BUILD_FOLDER_NAME, "ssg");
|
|
17505
18093
|
ensureDir(ssgOutDir);
|
|
17506
18094
|
for (const route of routes) {
|
|
17507
18095
|
if (route.dynamic !== "force-static") continue;
|
|
@@ -17556,36 +18144,36 @@ async function buildStaticPages(projectRoot, routes, config) {
|
|
|
17556
18144
|
}
|
|
17557
18145
|
|
|
17558
18146
|
// modules/build/bundler/server.ts
|
|
17559
|
-
var
|
|
17560
|
-
var
|
|
18147
|
+
var import_path33 = __toESM(require("path"));
|
|
18148
|
+
var import_fs23 = __toESM(require("fs"));
|
|
17561
18149
|
var import_esbuild = __toESM(require("esbuild"));
|
|
17562
18150
|
init_globals();
|
|
17563
18151
|
var SERVER_FILES = [INIT_FILE_NAME, CONFIG_FILE_NAME];
|
|
17564
18152
|
function createPathAliasPlugin(projectRoot, outDir) {
|
|
17565
18153
|
const aliases = loadAliasesFromTsconfig(projectRoot);
|
|
17566
|
-
const tsconfigPath =
|
|
18154
|
+
const tsconfigPath = import_path33.default.join(projectRoot, "tsconfig.json");
|
|
17567
18155
|
let baseUrl = ".";
|
|
17568
|
-
if (
|
|
18156
|
+
if (import_fs23.default.existsSync(tsconfigPath)) {
|
|
17569
18157
|
try {
|
|
17570
|
-
const tsconfig = JSON.parse(
|
|
18158
|
+
const tsconfig = JSON.parse(import_fs23.default.readFileSync(tsconfigPath, "utf-8"));
|
|
17571
18159
|
baseUrl = tsconfig.compilerOptions?.baseUrl ?? ".";
|
|
17572
18160
|
} catch {
|
|
17573
18161
|
}
|
|
17574
18162
|
}
|
|
17575
18163
|
function resolveAliasToRelative(importPath, sourceFile) {
|
|
17576
|
-
if (importPath.startsWith(".") || importPath.startsWith("/") ||
|
|
18164
|
+
if (importPath.startsWith(".") || importPath.startsWith("/") || import_path33.default.isAbsolute(importPath) || importPath.includes("node_modules")) {
|
|
17577
18165
|
return null;
|
|
17578
18166
|
}
|
|
17579
18167
|
for (const [aliasKey, aliasPath] of Object.entries(aliases)) {
|
|
17580
18168
|
if (importPath.startsWith(aliasKey + "/") || importPath === aliasKey) {
|
|
17581
18169
|
const restPath = importPath.startsWith(aliasKey + "/") ? importPath.slice(aliasKey.length + 1) : "";
|
|
17582
|
-
const resolvedPath = restPath ?
|
|
18170
|
+
const resolvedPath = restPath ? import_path33.default.join(aliasPath, restPath) : aliasPath;
|
|
17583
18171
|
let actualPath = null;
|
|
17584
18172
|
const extensions = [".ts", ".tsx", ".js", ".jsx", ".json"];
|
|
17585
|
-
if (
|
|
18173
|
+
if (import_fs23.default.existsSync(resolvedPath) && import_fs23.default.statSync(resolvedPath).isDirectory()) {
|
|
17586
18174
|
for (const ext of extensions) {
|
|
17587
|
-
const indexPath =
|
|
17588
|
-
if (
|
|
18175
|
+
const indexPath = import_path33.default.join(resolvedPath, `index${ext}`);
|
|
18176
|
+
if (import_fs23.default.existsSync(indexPath)) {
|
|
17589
18177
|
actualPath = indexPath;
|
|
17590
18178
|
break;
|
|
17591
18179
|
}
|
|
@@ -17593,20 +18181,20 @@ function createPathAliasPlugin(projectRoot, outDir) {
|
|
|
17593
18181
|
} else {
|
|
17594
18182
|
for (const ext of extensions) {
|
|
17595
18183
|
const filePath = resolvedPath + ext;
|
|
17596
|
-
if (
|
|
18184
|
+
if (import_fs23.default.existsSync(filePath)) {
|
|
17597
18185
|
actualPath = filePath;
|
|
17598
18186
|
break;
|
|
17599
18187
|
}
|
|
17600
18188
|
}
|
|
17601
|
-
if (!actualPath &&
|
|
18189
|
+
if (!actualPath && import_fs23.default.existsSync(resolvedPath)) {
|
|
17602
18190
|
actualPath = resolvedPath;
|
|
17603
18191
|
}
|
|
17604
18192
|
}
|
|
17605
18193
|
if (actualPath) {
|
|
17606
|
-
const relativePath =
|
|
18194
|
+
const relativePath = import_path33.default.relative(outDir, actualPath);
|
|
17607
18195
|
const normalizedPath = relativePath.replace(/\\/g, "/");
|
|
17608
18196
|
const finalPath = normalizedPath.startsWith(".") ? normalizedPath : `./${normalizedPath}`;
|
|
17609
|
-
const ext =
|
|
18197
|
+
const ext = import_path33.default.extname(finalPath);
|
|
17610
18198
|
const pathWithoutExt = ext === ".json" ? finalPath : finalPath.slice(0, -ext.length);
|
|
17611
18199
|
return pathWithoutExt;
|
|
17612
18200
|
}
|
|
@@ -17618,13 +18206,13 @@ function createPathAliasPlugin(projectRoot, outDir) {
|
|
|
17618
18206
|
name: "path-alias-resolver",
|
|
17619
18207
|
setup(build) {
|
|
17620
18208
|
build.onLoad({ filter: /\.(ts|tsx|js|jsx)$/ }, (args) => {
|
|
17621
|
-
const fileName =
|
|
18209
|
+
const fileName = import_path33.default.basename(args.path);
|
|
17622
18210
|
const isServerFile = SERVER_FILES.some((f) => fileName === `${f}.ts` || fileName === `${f}.tsx` || fileName === `${f}.js` || fileName === `${f}.jsx`);
|
|
17623
|
-
const isInProjectRoot =
|
|
18211
|
+
const isInProjectRoot = import_path33.default.dirname(args.path) === projectRoot;
|
|
17624
18212
|
if (!isServerFile || !isInProjectRoot) {
|
|
17625
18213
|
return null;
|
|
17626
18214
|
}
|
|
17627
|
-
const contents =
|
|
18215
|
+
const contents = import_fs23.default.readFileSync(args.path, "utf-8");
|
|
17628
18216
|
let transformed = contents;
|
|
17629
18217
|
const aliasPatterns = Object.keys(aliases).sort((a, b) => b.length - a.length);
|
|
17630
18218
|
for (const aliasKey of aliasPatterns) {
|
|
@@ -17644,7 +18232,7 @@ function createPathAliasPlugin(projectRoot, outDir) {
|
|
|
17644
18232
|
}
|
|
17645
18233
|
return {
|
|
17646
18234
|
contents: transformed,
|
|
17647
|
-
loader:
|
|
18235
|
+
loader: import_path33.default.extname(args.path).slice(1)
|
|
17648
18236
|
};
|
|
17649
18237
|
});
|
|
17650
18238
|
build.onResolve({ filter: /.*/ }, (args) => {
|
|
@@ -17663,9 +18251,9 @@ function createPathAliasPlugin(projectRoot, outDir) {
|
|
|
17663
18251
|
function collectAppSources(appDir) {
|
|
17664
18252
|
const entries = [];
|
|
17665
18253
|
function walk(dir) {
|
|
17666
|
-
const items =
|
|
18254
|
+
const items = import_fs23.default.readdirSync(dir, { withFileTypes: true });
|
|
17667
18255
|
for (const item of items) {
|
|
17668
|
-
const full =
|
|
18256
|
+
const full = import_path33.default.join(dir, item.name);
|
|
17669
18257
|
if (item.isDirectory()) {
|
|
17670
18258
|
walk(full);
|
|
17671
18259
|
continue;
|
|
@@ -17682,7 +18270,7 @@ function collectAppSources(appDir) {
|
|
|
17682
18270
|
return entries;
|
|
17683
18271
|
}
|
|
17684
18272
|
async function buildServerApp(projectRoot, appDir) {
|
|
17685
|
-
const outDir =
|
|
18273
|
+
const outDir = import_path33.default.join(projectRoot, BUILD_FOLDER_NAME, "server");
|
|
17686
18274
|
const entryPoints = collectAppSources(appDir);
|
|
17687
18275
|
ensureDir(outDir);
|
|
17688
18276
|
if (entryPoints.length === 0) {
|
|
@@ -17700,14 +18288,14 @@ async function buildServerApp(projectRoot, appDir) {
|
|
|
17700
18288
|
bundle: true,
|
|
17701
18289
|
splitting: false,
|
|
17702
18290
|
logLevel: "info",
|
|
17703
|
-
tsconfig:
|
|
18291
|
+
tsconfig: import_path33.default.join(projectRoot, "tsconfig.json"),
|
|
17704
18292
|
packages: "external"
|
|
17705
18293
|
});
|
|
17706
18294
|
const pathAliasPlugin = createPathAliasPlugin(projectRoot, outDir);
|
|
17707
18295
|
for (const fileName of SERVER_FILES) {
|
|
17708
|
-
const initTS =
|
|
17709
|
-
const initJS =
|
|
17710
|
-
if (
|
|
18296
|
+
const initTS = import_path33.default.join(projectRoot, `${fileName}.ts`);
|
|
18297
|
+
const initJS = import_path33.default.join(outDir, `${fileName}.js`);
|
|
18298
|
+
if (import_fs23.default.existsSync(initTS)) {
|
|
17711
18299
|
await import_esbuild.default.build({
|
|
17712
18300
|
entryPoints: [initTS],
|
|
17713
18301
|
outfile: initJS,
|
|
@@ -17718,7 +18306,7 @@ async function buildServerApp(projectRoot, appDir) {
|
|
|
17718
18306
|
sourcemap: true,
|
|
17719
18307
|
bundle: false,
|
|
17720
18308
|
logLevel: "info",
|
|
17721
|
-
tsconfig:
|
|
18309
|
+
tsconfig: import_path33.default.join(projectRoot, "tsconfig.json"),
|
|
17722
18310
|
plugins: [pathAliasPlugin]
|
|
17723
18311
|
});
|
|
17724
18312
|
}
|
|
@@ -17769,6 +18357,7 @@ async function buildApp(options = {}) {
|
|
|
17769
18357
|
});
|
|
17770
18358
|
writeClientBoostrapManifest(projectRoot);
|
|
17771
18359
|
writeClientRoutesManifest(routes, projectRoot);
|
|
18360
|
+
await writeRewritesManifest(projectRoot);
|
|
17772
18361
|
await buildClientBundle(projectRoot);
|
|
17773
18362
|
await buildStaticPages(projectRoot, routes, config);
|
|
17774
18363
|
delete process.env.LOLY_BUILD;
|
|
@@ -18477,13 +19066,22 @@ async function handleNormalRoute(nextUrl, json, routes, setState) {
|
|
|
18477
19066
|
theme
|
|
18478
19067
|
// Always include theme
|
|
18479
19068
|
};
|
|
18480
|
-
const
|
|
19069
|
+
const pathnameForMatch = json.pathname || nextUrl;
|
|
19070
|
+
let matched = matchRouteClient(pathnameForMatch, routes);
|
|
19071
|
+
if (!matched) {
|
|
19072
|
+
matched = matchRouteClient(nextUrl, routes);
|
|
19073
|
+
}
|
|
18481
19074
|
if (!matched) {
|
|
19075
|
+
console.warn(
|
|
19076
|
+
`[client] Server returned data for ${nextUrl} but no route match found. Available routes:`,
|
|
19077
|
+
routes.map((r) => r.pattern)
|
|
19078
|
+
);
|
|
18482
19079
|
window.location.href = nextUrl;
|
|
18483
19080
|
return false;
|
|
18484
19081
|
}
|
|
19082
|
+
const finalPathname = json.pathname || nextUrl;
|
|
18485
19083
|
const windowData = {
|
|
18486
|
-
pathname:
|
|
19084
|
+
pathname: finalPathname,
|
|
18487
19085
|
params: matched.params,
|
|
18488
19086
|
props: combinedProps,
|
|
18489
19087
|
metadata: json.metadata ?? null,
|
|
@@ -18882,8 +19480,9 @@ function initializeRouterData(initialUrl, initialData) {
|
|
|
18882
19480
|
let routerData = getRouterData();
|
|
18883
19481
|
if (!routerData) {
|
|
18884
19482
|
const url = new URL(initialUrl, window.location.origin);
|
|
19483
|
+
const pathname = initialData?.pathname || url.pathname;
|
|
18885
19484
|
routerData = {
|
|
18886
|
-
pathname
|
|
19485
|
+
pathname,
|
|
18887
19486
|
params: initialData?.params || {},
|
|
18888
19487
|
searchParams: Object.fromEntries(url.searchParams.entries())
|
|
18889
19488
|
};
|
|
@@ -18942,11 +19541,12 @@ function bootstrapClient(routes, notFoundRoute, errorRoute = null) {
|
|
|
18942
19541
|
return;
|
|
18943
19542
|
}
|
|
18944
19543
|
const initialData = getWindowData();
|
|
18945
|
-
const initialUrl = window.location.pathname + window.location.search;
|
|
19544
|
+
const initialUrl = (initialData?.pathname || window.location.pathname) + window.location.search;
|
|
18946
19545
|
if (initialData?.props) {
|
|
18947
19546
|
setPreservedLayoutProps(initialData.props);
|
|
18948
19547
|
}
|
|
18949
|
-
|
|
19548
|
+
const routerPathname = initialData?.pathname || window.location.pathname;
|
|
19549
|
+
initializeRouterData(routerPathname + window.location.search, initialData);
|
|
18950
19550
|
await hydrateInitialRoute(
|
|
18951
19551
|
container,
|
|
18952
19552
|
initialUrl,
|
|
@@ -18993,11 +19593,11 @@ var ValidationError = class extends Error {
|
|
|
18993
19593
|
format() {
|
|
18994
19594
|
const formatted = {};
|
|
18995
19595
|
for (const error of this.errors) {
|
|
18996
|
-
const
|
|
18997
|
-
if (!formatted[
|
|
18998
|
-
formatted[
|
|
19596
|
+
const path30 = error.path.join(".");
|
|
19597
|
+
if (!formatted[path30]) {
|
|
19598
|
+
formatted[path30] = [];
|
|
18999
19599
|
}
|
|
19000
|
-
formatted[
|
|
19600
|
+
formatted[path30].push(error.message);
|
|
19001
19601
|
}
|
|
19002
19602
|
return formatted;
|
|
19003
19603
|
}
|