@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/cli.cjs
CHANGED
|
@@ -9866,7 +9866,7 @@ var require_built3 = __commonJS({
|
|
|
9866
9866
|
});
|
|
9867
9867
|
|
|
9868
9868
|
// modules/cli/index.ts
|
|
9869
|
-
var
|
|
9869
|
+
var import_path34 = __toESM(require("path"));
|
|
9870
9870
|
var import_process = __toESM(require("process"));
|
|
9871
9871
|
|
|
9872
9872
|
// modules/router/loader-pages.ts
|
|
@@ -9878,10 +9878,17 @@ var PAGE_FILE_REGEX = /^page\.(tsx|ts|jsx|js)$/;
|
|
|
9878
9878
|
var LAYOUT_FILE_BASENAME = "layout";
|
|
9879
9879
|
|
|
9880
9880
|
// modules/router/path.ts
|
|
9881
|
+
function isRouteGroup(dirName) {
|
|
9882
|
+
return dirName.startsWith("(") && dirName.endsWith(")");
|
|
9883
|
+
}
|
|
9881
9884
|
function buildRoutePathFromDir(relDir) {
|
|
9882
9885
|
if (!relDir || relDir === ".") return "/";
|
|
9883
9886
|
const clean = relDir.replace(/\\/g, "/");
|
|
9884
|
-
|
|
9887
|
+
const segments = clean.split("/").filter((seg) => {
|
|
9888
|
+
return !isRouteGroup(seg);
|
|
9889
|
+
});
|
|
9890
|
+
if (segments.length === 0) return "/";
|
|
9891
|
+
return "/" + segments.join("/");
|
|
9885
9892
|
}
|
|
9886
9893
|
function buildRegexFromRoutePath(routePath) {
|
|
9887
9894
|
const segments = routePath.split("/").filter(Boolean);
|
|
@@ -10097,13 +10104,17 @@ function validateRoutes(routes, appDir) {
|
|
|
10097
10104
|
}
|
|
10098
10105
|
for (const [pattern, duplicateRoutes] of routePatterns.entries()) {
|
|
10099
10106
|
if (duplicateRoutes.length > 1) {
|
|
10100
|
-
const files = duplicateRoutes.map(
|
|
10101
|
-
|
|
10102
|
-
|
|
10107
|
+
const files = duplicateRoutes.map((r) => {
|
|
10108
|
+
const relPath = r.pageFile ? import_path3.default.relative(appDir, r.pageFile) : "unknown";
|
|
10109
|
+
const segments = relPath.split(import_path3.default.sep);
|
|
10110
|
+
const hasRouteGroup = segments.some((seg) => isRouteGroup(seg));
|
|
10111
|
+
return hasRouteGroup ? `${relPath} (inside route group)` : relPath;
|
|
10112
|
+
}).join(", ");
|
|
10103
10113
|
errors.push(
|
|
10104
10114
|
`Duplicate route pattern "${pattern}" found in multiple files:
|
|
10105
10115
|
${files}
|
|
10106
|
-
\u{1F4A1} Suggestion:
|
|
10116
|
+
\u{1F4A1} Suggestion: Route groups (directories in parentheses) don't appear in URLs.
|
|
10117
|
+
Ensure each route has a unique path pattern after route groups are ignored.`
|
|
10107
10118
|
);
|
|
10108
10119
|
}
|
|
10109
10120
|
}
|
|
@@ -10380,12 +10391,13 @@ function loadApiRoutes(appDir) {
|
|
|
10380
10391
|
|
|
10381
10392
|
// modules/router/matcher.ts
|
|
10382
10393
|
function matchRoute(routes, urlPath) {
|
|
10394
|
+
const normalizedPath = urlPath.replace(/\/$/, "") || "/";
|
|
10383
10395
|
for (const route of routes) {
|
|
10384
|
-
const match = route.regex.exec(
|
|
10396
|
+
const match = route.regex.exec(normalizedPath);
|
|
10385
10397
|
if (!match) continue;
|
|
10386
10398
|
const params = {};
|
|
10387
10399
|
route.paramNames.forEach((name, idx) => {
|
|
10388
|
-
params[name] = match[idx + 1];
|
|
10400
|
+
params[name] = decodeURIComponent(match[idx + 1] || "");
|
|
10389
10401
|
});
|
|
10390
10402
|
return { route, params };
|
|
10391
10403
|
}
|
|
@@ -11395,34 +11407,504 @@ function loadErrorRouteFromFilesystem(appDir) {
|
|
|
11395
11407
|
};
|
|
11396
11408
|
}
|
|
11397
11409
|
|
|
11410
|
+
// modules/router/rewrites.ts
|
|
11411
|
+
function parseRewritePattern(pattern) {
|
|
11412
|
+
const cleanPattern = pattern.replace(/^\/+|\/+$/g, "") || "";
|
|
11413
|
+
if (!cleanPattern) {
|
|
11414
|
+
return {
|
|
11415
|
+
regex: /^\/?$/,
|
|
11416
|
+
paramNames: []
|
|
11417
|
+
};
|
|
11418
|
+
}
|
|
11419
|
+
const segments = cleanPattern.split("/").filter(Boolean);
|
|
11420
|
+
const paramNames = [];
|
|
11421
|
+
const regexParts = [];
|
|
11422
|
+
for (let i = 0; i < segments.length; i++) {
|
|
11423
|
+
const seg = segments[i];
|
|
11424
|
+
if (seg === "*") {
|
|
11425
|
+
if (i !== segments.length - 1) {
|
|
11426
|
+
throw new Error(
|
|
11427
|
+
`Catch-all "*" in "${pattern}" must be the last segment.`
|
|
11428
|
+
);
|
|
11429
|
+
}
|
|
11430
|
+
regexParts.push("(.+)");
|
|
11431
|
+
continue;
|
|
11432
|
+
}
|
|
11433
|
+
if (seg.endsWith("*") && seg.startsWith(":")) {
|
|
11434
|
+
const paramName = seg.slice(1, -1);
|
|
11435
|
+
if (i !== segments.length - 1) {
|
|
11436
|
+
throw new Error(
|
|
11437
|
+
`Catch-all segment "${seg}" in "${pattern}" must be the last segment.`
|
|
11438
|
+
);
|
|
11439
|
+
}
|
|
11440
|
+
paramNames.push(paramName);
|
|
11441
|
+
regexParts.push("(.+)");
|
|
11442
|
+
continue;
|
|
11443
|
+
}
|
|
11444
|
+
if (seg.startsWith(":") && seg.length > 1) {
|
|
11445
|
+
const paramName = seg.slice(1);
|
|
11446
|
+
paramNames.push(paramName);
|
|
11447
|
+
regexParts.push("([^/]+)");
|
|
11448
|
+
continue;
|
|
11449
|
+
}
|
|
11450
|
+
const escaped = seg.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
11451
|
+
regexParts.push(escaped);
|
|
11452
|
+
}
|
|
11453
|
+
const regexSource = "^/?" + regexParts.join("/") + "/?$";
|
|
11454
|
+
const regex = new RegExp(regexSource);
|
|
11455
|
+
return { regex, paramNames };
|
|
11456
|
+
}
|
|
11457
|
+
function extractHostParams(hostPattern, actualHost) {
|
|
11458
|
+
const regexPattern = hostPattern.replace(/:([^.]+)/g, "([^.]+)").replace(/\./g, "\\.").replace(/\*/g, ".*");
|
|
11459
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
|
11460
|
+
const match = regex.exec(actualHost);
|
|
11461
|
+
if (!match) return null;
|
|
11462
|
+
const paramNames = [];
|
|
11463
|
+
const paramPattern = /:([^.]+)/g;
|
|
11464
|
+
let paramMatch;
|
|
11465
|
+
while ((paramMatch = paramPattern.exec(hostPattern)) !== null) {
|
|
11466
|
+
paramNames.push(paramMatch[1]);
|
|
11467
|
+
}
|
|
11468
|
+
const params = {};
|
|
11469
|
+
paramNames.forEach((name, idx) => {
|
|
11470
|
+
params[name] = match[idx + 1] || "";
|
|
11471
|
+
});
|
|
11472
|
+
return params;
|
|
11473
|
+
}
|
|
11474
|
+
function evaluateRewriteConditions(conditions, req) {
|
|
11475
|
+
const extractedParams = {};
|
|
11476
|
+
for (const condition of conditions) {
|
|
11477
|
+
switch (condition.type) {
|
|
11478
|
+
case "host": {
|
|
11479
|
+
const hostWithPort = req.get("host") || req.hostname || req.get("x-forwarded-host")?.split(",")[0] || "";
|
|
11480
|
+
const host = hostWithPort.split(":")[0];
|
|
11481
|
+
if (process.env.NODE_ENV === "development") {
|
|
11482
|
+
console.log("[rewrites] Host matching:", {
|
|
11483
|
+
pattern: condition.value,
|
|
11484
|
+
actualHost: host,
|
|
11485
|
+
hostWithPort,
|
|
11486
|
+
reqHost: req.get("host"),
|
|
11487
|
+
reqHostname: req.hostname
|
|
11488
|
+
});
|
|
11489
|
+
}
|
|
11490
|
+
const hostParams = extractHostParams(condition.value, host);
|
|
11491
|
+
if (!hostParams) {
|
|
11492
|
+
if (process.env.NODE_ENV === "development") {
|
|
11493
|
+
console.log("[rewrites] Host params extraction failed:", {
|
|
11494
|
+
pattern: condition.value,
|
|
11495
|
+
actualHost: host
|
|
11496
|
+
});
|
|
11497
|
+
}
|
|
11498
|
+
return { matches: false, params: {} };
|
|
11499
|
+
}
|
|
11500
|
+
Object.assign(extractedParams, hostParams);
|
|
11501
|
+
break;
|
|
11502
|
+
}
|
|
11503
|
+
case "header": {
|
|
11504
|
+
if (!condition.key) {
|
|
11505
|
+
return { matches: false, params: {} };
|
|
11506
|
+
}
|
|
11507
|
+
const headerValue = req.get(condition.key.toLowerCase());
|
|
11508
|
+
if (!headerValue || headerValue !== condition.value) {
|
|
11509
|
+
return { matches: false, params: {} };
|
|
11510
|
+
}
|
|
11511
|
+
break;
|
|
11512
|
+
}
|
|
11513
|
+
case "cookie": {
|
|
11514
|
+
if (!condition.key) {
|
|
11515
|
+
return { matches: false, params: {} };
|
|
11516
|
+
}
|
|
11517
|
+
const cookieValue = req.cookies?.[condition.key];
|
|
11518
|
+
if (!cookieValue || cookieValue !== condition.value) {
|
|
11519
|
+
return { matches: false, params: {} };
|
|
11520
|
+
}
|
|
11521
|
+
break;
|
|
11522
|
+
}
|
|
11523
|
+
case "query": {
|
|
11524
|
+
if (!condition.key) {
|
|
11525
|
+
return { matches: false, params: {} };
|
|
11526
|
+
}
|
|
11527
|
+
const queryValue = req.query[condition.key];
|
|
11528
|
+
if (!queryValue || String(queryValue) !== condition.value) {
|
|
11529
|
+
return { matches: false, params: {} };
|
|
11530
|
+
}
|
|
11531
|
+
break;
|
|
11532
|
+
}
|
|
11533
|
+
default:
|
|
11534
|
+
return { matches: false, params: {} };
|
|
11535
|
+
}
|
|
11536
|
+
}
|
|
11537
|
+
return { matches: true, params: extractedParams };
|
|
11538
|
+
}
|
|
11539
|
+
function replaceDestinationParams(destination, params) {
|
|
11540
|
+
let result = destination;
|
|
11541
|
+
for (const [key, value] of Object.entries(params)) {
|
|
11542
|
+
const pattern = new RegExp(`:${key}(?:\\*)?`, "g");
|
|
11543
|
+
result = result.replace(pattern, value);
|
|
11544
|
+
}
|
|
11545
|
+
return result;
|
|
11546
|
+
}
|
|
11547
|
+
async function processRewrites(urlPath, compiledRewrites, req) {
|
|
11548
|
+
const normalizedPath = urlPath.replace(/\/$/, "") || "/";
|
|
11549
|
+
if (normalizedPath.startsWith("/static/") || // Static assets (client.js, client.css, etc.)
|
|
11550
|
+
normalizedPath.startsWith("/__fw/") || // Framework internal routes (hot reload, etc.)
|
|
11551
|
+
normalizedPath === "/favicon.ico" || // Favicon
|
|
11552
|
+
normalizedPath.startsWith("/wss/")) {
|
|
11553
|
+
if (process.env.NODE_ENV === "development") {
|
|
11554
|
+
console.log("[rewrites] Skipping rewrite for system route:", normalizedPath);
|
|
11555
|
+
}
|
|
11556
|
+
return null;
|
|
11557
|
+
}
|
|
11558
|
+
if (process.env.NODE_ENV === "development") {
|
|
11559
|
+
console.log("[rewrites] Processing rewrites:", {
|
|
11560
|
+
urlPath,
|
|
11561
|
+
normalizedPath,
|
|
11562
|
+
host: req.get("host"),
|
|
11563
|
+
hostname: req.hostname,
|
|
11564
|
+
compiledRewritesCount: compiledRewrites.length
|
|
11565
|
+
});
|
|
11566
|
+
}
|
|
11567
|
+
for (const rewrite of compiledRewrites) {
|
|
11568
|
+
let conditionParams = {};
|
|
11569
|
+
if (rewrite.has && rewrite.has.length > 0) {
|
|
11570
|
+
const conditionResult = evaluateRewriteConditions(rewrite.has, req);
|
|
11571
|
+
if (!conditionResult.matches) {
|
|
11572
|
+
if (process.env.NODE_ENV === "development") {
|
|
11573
|
+
console.log("[rewrites] Condition not matched:", {
|
|
11574
|
+
source: rewrite.source,
|
|
11575
|
+
conditions: rewrite.has
|
|
11576
|
+
});
|
|
11577
|
+
}
|
|
11578
|
+
continue;
|
|
11579
|
+
}
|
|
11580
|
+
conditionParams = conditionResult.params;
|
|
11581
|
+
if (process.env.NODE_ENV === "development") {
|
|
11582
|
+
console.log("[rewrites] Condition matched:", {
|
|
11583
|
+
source: rewrite.source,
|
|
11584
|
+
conditionParams
|
|
11585
|
+
});
|
|
11586
|
+
}
|
|
11587
|
+
}
|
|
11588
|
+
const sourceMatch = rewrite.sourceRegex.exec(normalizedPath);
|
|
11589
|
+
if (!sourceMatch) {
|
|
11590
|
+
if (process.env.NODE_ENV === "development") {
|
|
11591
|
+
console.log("[rewrites] Source pattern not matched:", {
|
|
11592
|
+
source: rewrite.source,
|
|
11593
|
+
normalizedPath,
|
|
11594
|
+
sourceRegex: rewrite.sourceRegex.toString()
|
|
11595
|
+
});
|
|
11596
|
+
}
|
|
11597
|
+
continue;
|
|
11598
|
+
}
|
|
11599
|
+
if (process.env.NODE_ENV === "development") {
|
|
11600
|
+
console.log("[rewrites] Source pattern matched:", {
|
|
11601
|
+
source: rewrite.source,
|
|
11602
|
+
normalizedPath,
|
|
11603
|
+
match: sourceMatch[0]
|
|
11604
|
+
});
|
|
11605
|
+
}
|
|
11606
|
+
const sourceParams = {};
|
|
11607
|
+
rewrite.sourceParamNames.forEach((name, idx) => {
|
|
11608
|
+
sourceParams[name] = decodeURIComponent(sourceMatch[idx + 1] || "");
|
|
11609
|
+
});
|
|
11610
|
+
const allParams = { ...sourceParams, ...conditionParams };
|
|
11611
|
+
let destination;
|
|
11612
|
+
if (typeof rewrite.destination === "function") {
|
|
11613
|
+
destination = await rewrite.destination(allParams, req);
|
|
11614
|
+
} else {
|
|
11615
|
+
destination = replaceDestinationParams(rewrite.destination, allParams);
|
|
11616
|
+
}
|
|
11617
|
+
const normalizedDestination = destination.replace(/\/+/g, "/").replace(/^([^/])/, "/$1").replace(/\/$/, "") || "/";
|
|
11618
|
+
if (process.env.NODE_ENV === "development") {
|
|
11619
|
+
console.log("[rewrites] Rewrite successful:", {
|
|
11620
|
+
originalPath: urlPath,
|
|
11621
|
+
rewrittenPath: normalizedDestination,
|
|
11622
|
+
allParams
|
|
11623
|
+
});
|
|
11624
|
+
}
|
|
11625
|
+
return {
|
|
11626
|
+
rewrittenPath: normalizedDestination,
|
|
11627
|
+
extractedParams: allParams
|
|
11628
|
+
};
|
|
11629
|
+
}
|
|
11630
|
+
return null;
|
|
11631
|
+
}
|
|
11632
|
+
function validateRewrites(rules) {
|
|
11633
|
+
for (const rule of rules) {
|
|
11634
|
+
if (typeof rule.destination === "string") {
|
|
11635
|
+
if (rule.source === rule.destination) {
|
|
11636
|
+
console.warn(
|
|
11637
|
+
`[framework][rewrites] Rewrite rule has identical source and destination: "${rule.source}". This may cause issues.`
|
|
11638
|
+
);
|
|
11639
|
+
}
|
|
11640
|
+
}
|
|
11641
|
+
}
|
|
11642
|
+
const sources = /* @__PURE__ */ new Set();
|
|
11643
|
+
for (const rule of rules) {
|
|
11644
|
+
if (sources.has(rule.source)) {
|
|
11645
|
+
console.warn(
|
|
11646
|
+
`[framework][rewrites] Duplicate rewrite source pattern: "${rule.source}". Only the first match will be used.`
|
|
11647
|
+
);
|
|
11648
|
+
}
|
|
11649
|
+
sources.add(rule.source);
|
|
11650
|
+
}
|
|
11651
|
+
}
|
|
11652
|
+
function compileRewriteRules(rules) {
|
|
11653
|
+
validateRewrites(rules);
|
|
11654
|
+
return rules.map((rule) => {
|
|
11655
|
+
const { regex, paramNames } = parseRewritePattern(rule.source);
|
|
11656
|
+
let hostRegex;
|
|
11657
|
+
let hostParamNames;
|
|
11658
|
+
if (rule.has) {
|
|
11659
|
+
const hostCondition = rule.has.find((c) => c.type === "host");
|
|
11660
|
+
if (hostCondition) {
|
|
11661
|
+
const hostPattern = hostCondition.value;
|
|
11662
|
+
const hostRegexPattern = hostPattern.replace(/:([^.]+)/g, "([^.]+)").replace(/\./g, "\\.").replace(/\*/g, ".*");
|
|
11663
|
+
hostRegex = new RegExp(`^${hostRegexPattern}$`);
|
|
11664
|
+
hostParamNames = [];
|
|
11665
|
+
const paramPattern = /:([^.]+)/g;
|
|
11666
|
+
let paramMatch;
|
|
11667
|
+
while ((paramMatch = paramPattern.exec(hostPattern)) !== null) {
|
|
11668
|
+
hostParamNames.push(paramMatch[1]);
|
|
11669
|
+
}
|
|
11670
|
+
}
|
|
11671
|
+
}
|
|
11672
|
+
return {
|
|
11673
|
+
source: rule.source,
|
|
11674
|
+
sourceRegex: regex,
|
|
11675
|
+
sourceParamNames: paramNames,
|
|
11676
|
+
destination: rule.destination,
|
|
11677
|
+
has: rule.has,
|
|
11678
|
+
hostRegex,
|
|
11679
|
+
hostParamNames
|
|
11680
|
+
};
|
|
11681
|
+
});
|
|
11682
|
+
}
|
|
11683
|
+
|
|
11684
|
+
// modules/router/rewrites-loader.ts
|
|
11685
|
+
var import_fs10 = __toESM(require("fs"));
|
|
11686
|
+
var import_path12 = __toESM(require("path"));
|
|
11687
|
+
var FilesystemRewriteLoader = class {
|
|
11688
|
+
// Maximum cache age in ms (1 second fallback)
|
|
11689
|
+
constructor(projectRoot) {
|
|
11690
|
+
this.projectRoot = projectRoot;
|
|
11691
|
+
this.cache = null;
|
|
11692
|
+
this.cacheMaxAge = 1e3;
|
|
11693
|
+
}
|
|
11694
|
+
/**
|
|
11695
|
+
* Invalidates the cache, forcing a reload on next access.
|
|
11696
|
+
*/
|
|
11697
|
+
invalidateCache() {
|
|
11698
|
+
this.cache = null;
|
|
11699
|
+
}
|
|
11700
|
+
/**
|
|
11701
|
+
* Finds the rewrites config file.
|
|
11702
|
+
* Looks for rewrites.config.ts, rewrites.config.js, or rewrites.config.json
|
|
11703
|
+
*/
|
|
11704
|
+
findRewritesConfig() {
|
|
11705
|
+
const candidates = [
|
|
11706
|
+
import_path12.default.join(this.projectRoot, "rewrites.config.ts"),
|
|
11707
|
+
import_path12.default.join(this.projectRoot, "rewrites.config.js"),
|
|
11708
|
+
import_path12.default.join(this.projectRoot, "rewrites.config.json")
|
|
11709
|
+
];
|
|
11710
|
+
for (const candidate of candidates) {
|
|
11711
|
+
if (import_fs10.default.existsSync(candidate)) {
|
|
11712
|
+
return candidate;
|
|
11713
|
+
}
|
|
11714
|
+
}
|
|
11715
|
+
return null;
|
|
11716
|
+
}
|
|
11717
|
+
/**
|
|
11718
|
+
* Checks if the rewrites config file has changed.
|
|
11719
|
+
*/
|
|
11720
|
+
hasConfigChanged(configPath) {
|
|
11721
|
+
if (!this.cache || !this.cache.fileStats) {
|
|
11722
|
+
return true;
|
|
11723
|
+
}
|
|
11724
|
+
if (!import_fs10.default.existsSync(configPath)) {
|
|
11725
|
+
return this.cache.rewrites.length > 0;
|
|
11726
|
+
}
|
|
11727
|
+
const stats = import_fs10.default.statSync(configPath);
|
|
11728
|
+
const cachedStats = this.cache.fileStats;
|
|
11729
|
+
return stats.mtimeMs !== cachedStats.mtime || stats.size !== cachedStats.size;
|
|
11730
|
+
}
|
|
11731
|
+
/**
|
|
11732
|
+
* Loads rewrites from a config file.
|
|
11733
|
+
*/
|
|
11734
|
+
async loadRewritesFromFile(configPath) {
|
|
11735
|
+
const ext = import_path12.default.extname(configPath);
|
|
11736
|
+
if (ext === ".json") {
|
|
11737
|
+
const content = import_fs10.default.readFileSync(configPath, "utf-8");
|
|
11738
|
+
const config2 = JSON.parse(content);
|
|
11739
|
+
return Array.isArray(config2) ? config2 : [];
|
|
11740
|
+
}
|
|
11741
|
+
delete require.cache[require.resolve(configPath)];
|
|
11742
|
+
const mod = require(configPath);
|
|
11743
|
+
const config = mod.default || mod;
|
|
11744
|
+
if (typeof config === "function") {
|
|
11745
|
+
return await config();
|
|
11746
|
+
}
|
|
11747
|
+
if (Array.isArray(config)) {
|
|
11748
|
+
return config;
|
|
11749
|
+
}
|
|
11750
|
+
throw new Error(
|
|
11751
|
+
`Invalid rewrites config in ${configPath}. Expected array or function returning array.`
|
|
11752
|
+
);
|
|
11753
|
+
}
|
|
11754
|
+
/**
|
|
11755
|
+
* Checks if cache is still valid, invalidates if config changed.
|
|
11756
|
+
*/
|
|
11757
|
+
ensureCacheValid() {
|
|
11758
|
+
if (!this.cache) {
|
|
11759
|
+
return;
|
|
11760
|
+
}
|
|
11761
|
+
const now = Date.now();
|
|
11762
|
+
if (now - this.cache.timestamp > this.cacheMaxAge) {
|
|
11763
|
+
const configPath = this.findRewritesConfig();
|
|
11764
|
+
if (configPath && this.hasConfigChanged(configPath)) {
|
|
11765
|
+
this.cache = null;
|
|
11766
|
+
} else {
|
|
11767
|
+
this.cache.timestamp = now;
|
|
11768
|
+
}
|
|
11769
|
+
}
|
|
11770
|
+
}
|
|
11771
|
+
async loadRewrites() {
|
|
11772
|
+
this.ensureCacheValid();
|
|
11773
|
+
const configPath = this.findRewritesConfig();
|
|
11774
|
+
if (!configPath) {
|
|
11775
|
+
if (this.cache && this.cache.rewrites.length === 0) {
|
|
11776
|
+
return this.cache.rewrites;
|
|
11777
|
+
}
|
|
11778
|
+
this.cache = {
|
|
11779
|
+
rewrites: [],
|
|
11780
|
+
fileStats: null,
|
|
11781
|
+
timestamp: Date.now()
|
|
11782
|
+
};
|
|
11783
|
+
return [];
|
|
11784
|
+
}
|
|
11785
|
+
if (!this.cache || this.hasConfigChanged(configPath)) {
|
|
11786
|
+
const rules = await this.loadRewritesFromFile(configPath);
|
|
11787
|
+
const compiled = compileRewriteRules(rules);
|
|
11788
|
+
const stats = import_fs10.default.statSync(configPath);
|
|
11789
|
+
const fileStats = {
|
|
11790
|
+
mtime: stats.mtimeMs,
|
|
11791
|
+
size: stats.size
|
|
11792
|
+
};
|
|
11793
|
+
this.cache = {
|
|
11794
|
+
rewrites: compiled,
|
|
11795
|
+
fileStats,
|
|
11796
|
+
timestamp: Date.now()
|
|
11797
|
+
};
|
|
11798
|
+
}
|
|
11799
|
+
return this.cache.rewrites;
|
|
11800
|
+
}
|
|
11801
|
+
};
|
|
11802
|
+
var ManifestRewriteLoader = class {
|
|
11803
|
+
constructor(projectRoot) {
|
|
11804
|
+
this.cache = null;
|
|
11805
|
+
this.manifestPath = import_path12.default.join(projectRoot, ".loly", "rewrites-manifest.json");
|
|
11806
|
+
}
|
|
11807
|
+
/**
|
|
11808
|
+
* Reads the rewrites manifest from disk.
|
|
11809
|
+
*/
|
|
11810
|
+
readManifest() {
|
|
11811
|
+
if (!import_fs10.default.existsSync(this.manifestPath)) {
|
|
11812
|
+
return null;
|
|
11813
|
+
}
|
|
11814
|
+
try {
|
|
11815
|
+
const content = import_fs10.default.readFileSync(this.manifestPath, "utf-8");
|
|
11816
|
+
return JSON.parse(content);
|
|
11817
|
+
} catch (error) {
|
|
11818
|
+
console.warn(
|
|
11819
|
+
`Failed to read rewrites manifest from ${this.manifestPath}:`,
|
|
11820
|
+
error
|
|
11821
|
+
);
|
|
11822
|
+
return null;
|
|
11823
|
+
}
|
|
11824
|
+
}
|
|
11825
|
+
async loadRewrites() {
|
|
11826
|
+
if (this.cache) {
|
|
11827
|
+
return this.cache;
|
|
11828
|
+
}
|
|
11829
|
+
const manifest = this.readManifest();
|
|
11830
|
+
if (!manifest || !manifest.rewrites) {
|
|
11831
|
+
this.cache = [];
|
|
11832
|
+
return [];
|
|
11833
|
+
}
|
|
11834
|
+
const compiled = compileRewriteRules(manifest.rewrites);
|
|
11835
|
+
this.cache = compiled;
|
|
11836
|
+
return compiled;
|
|
11837
|
+
}
|
|
11838
|
+
};
|
|
11839
|
+
function createRewriteLoader(projectRoot, isDev) {
|
|
11840
|
+
if (isDev) {
|
|
11841
|
+
return new FilesystemRewriteLoader(projectRoot);
|
|
11842
|
+
} else {
|
|
11843
|
+
return new ManifestRewriteLoader(projectRoot);
|
|
11844
|
+
}
|
|
11845
|
+
}
|
|
11846
|
+
|
|
11847
|
+
// modules/router/rewrites-manifest.ts
|
|
11848
|
+
var import_fs11 = __toESM(require("fs"));
|
|
11849
|
+
var import_path13 = __toESM(require("path"));
|
|
11850
|
+
init_globals();
|
|
11851
|
+
async function writeRewritesManifest(projectRoot) {
|
|
11852
|
+
const buildDir = import_path13.default.join(projectRoot, BUILD_FOLDER_NAME);
|
|
11853
|
+
if (!import_fs11.default.existsSync(buildDir)) {
|
|
11854
|
+
import_fs11.default.mkdirSync(buildDir, { recursive: true });
|
|
11855
|
+
}
|
|
11856
|
+
const manifestPath = import_path13.default.join(buildDir, "rewrites-manifest.json");
|
|
11857
|
+
const loader = createRewriteLoader(projectRoot, true);
|
|
11858
|
+
const compiledRewrites = await loader.loadRewrites();
|
|
11859
|
+
const serializableRules = [];
|
|
11860
|
+
for (const compiled of compiledRewrites) {
|
|
11861
|
+
if (typeof compiled.destination === "string") {
|
|
11862
|
+
serializableRules.push({
|
|
11863
|
+
source: compiled.source,
|
|
11864
|
+
destination: compiled.destination,
|
|
11865
|
+
has: compiled.has
|
|
11866
|
+
});
|
|
11867
|
+
} else {
|
|
11868
|
+
console.warn(
|
|
11869
|
+
`[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.`
|
|
11870
|
+
);
|
|
11871
|
+
}
|
|
11872
|
+
}
|
|
11873
|
+
const manifest = {
|
|
11874
|
+
version: 1,
|
|
11875
|
+
rewrites: serializableRules
|
|
11876
|
+
};
|
|
11877
|
+
import_fs11.default.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
11878
|
+
}
|
|
11879
|
+
|
|
11398
11880
|
// modules/build/bundler/client.ts
|
|
11399
11881
|
var import_core2 = require("@rspack/core");
|
|
11400
11882
|
|
|
11401
11883
|
// modules/build/config/client.ts
|
|
11402
|
-
var
|
|
11403
|
-
var
|
|
11884
|
+
var import_path15 = __toESM(require("path"));
|
|
11885
|
+
var import_fs13 = __toESM(require("fs"));
|
|
11404
11886
|
var import_core = require("@rspack/core");
|
|
11405
11887
|
|
|
11406
11888
|
// modules/build/utils/index.ts
|
|
11407
|
-
var
|
|
11408
|
-
var
|
|
11889
|
+
var import_fs12 = __toESM(require("fs"));
|
|
11890
|
+
var import_path14 = __toESM(require("path"));
|
|
11409
11891
|
function ensureDir(dir) {
|
|
11410
|
-
|
|
11892
|
+
import_fs12.default.mkdirSync(dir, { recursive: true });
|
|
11411
11893
|
}
|
|
11412
11894
|
function loadAliasesFromTsconfig(projectRoot) {
|
|
11413
|
-
const tsconfigPath =
|
|
11895
|
+
const tsconfigPath = import_path14.default.join(projectRoot, "tsconfig.json");
|
|
11414
11896
|
const aliases = {};
|
|
11415
|
-
if (!
|
|
11416
|
-
aliases["@app"] =
|
|
11897
|
+
if (!import_fs12.default.existsSync(tsconfigPath)) {
|
|
11898
|
+
aliases["@app"] = import_path14.default.resolve(projectRoot, "app");
|
|
11417
11899
|
return aliases;
|
|
11418
11900
|
}
|
|
11419
11901
|
let tsconfig;
|
|
11420
11902
|
try {
|
|
11421
|
-
tsconfig = JSON.parse(
|
|
11903
|
+
tsconfig = JSON.parse(import_fs12.default.readFileSync(tsconfigPath, "utf-8"));
|
|
11422
11904
|
} catch (err) {
|
|
11423
11905
|
console.warn("\u26A0\uFE0F [framework] Could not read tsconfig.json:", err instanceof Error ? err.message : String(err));
|
|
11424
11906
|
console.warn("\u{1F4A1} Using default path aliases. For custom aliases, ensure tsconfig.json is valid.");
|
|
11425
|
-
aliases["@app"] =
|
|
11907
|
+
aliases["@app"] = import_path14.default.resolve(projectRoot, "app");
|
|
11426
11908
|
return aliases;
|
|
11427
11909
|
}
|
|
11428
11910
|
const compilerOptions = tsconfig.compilerOptions ?? {};
|
|
@@ -11433,40 +11915,40 @@ function loadAliasesFromTsconfig(projectRoot) {
|
|
|
11433
11915
|
const aliasKey = aliasPattern.replace(/\/\*$/, "");
|
|
11434
11916
|
const firstTarget = targets[0];
|
|
11435
11917
|
const targetPath = firstTarget.replace(/\/\*$/, "");
|
|
11436
|
-
const resolved =
|
|
11918
|
+
const resolved = import_path14.default.resolve(projectRoot, baseUrl, targetPath);
|
|
11437
11919
|
aliases[aliasKey] = resolved;
|
|
11438
11920
|
}
|
|
11439
11921
|
if (!aliases["@app"]) {
|
|
11440
|
-
aliases["@app"] =
|
|
11922
|
+
aliases["@app"] = import_path14.default.resolve(projectRoot, "app");
|
|
11441
11923
|
}
|
|
11442
11924
|
return aliases;
|
|
11443
11925
|
}
|
|
11444
11926
|
function copyDirRecursive(srcDir, destDir) {
|
|
11445
|
-
if (!
|
|
11927
|
+
if (!import_fs12.default.existsSync(srcDir)) return;
|
|
11446
11928
|
ensureDir(destDir);
|
|
11447
|
-
const entries =
|
|
11929
|
+
const entries = import_fs12.default.readdirSync(srcDir, { withFileTypes: true });
|
|
11448
11930
|
for (const entry of entries) {
|
|
11449
|
-
const srcPath =
|
|
11450
|
-
const destPath =
|
|
11931
|
+
const srcPath = import_path14.default.join(srcDir, entry.name);
|
|
11932
|
+
const destPath = import_path14.default.join(destDir, entry.name);
|
|
11451
11933
|
if (entry.isDirectory()) {
|
|
11452
11934
|
copyDirRecursive(srcPath, destPath);
|
|
11453
11935
|
} else if (entry.isFile()) {
|
|
11454
|
-
|
|
11936
|
+
import_fs12.default.copyFileSync(srcPath, destPath);
|
|
11455
11937
|
}
|
|
11456
11938
|
}
|
|
11457
11939
|
}
|
|
11458
11940
|
function copyStaticAssets(projectRoot, outDir) {
|
|
11459
|
-
const assetsSrc =
|
|
11460
|
-
const assetsDest =
|
|
11941
|
+
const assetsSrc = import_path14.default.join(projectRoot, "assets");
|
|
11942
|
+
const assetsDest = import_path14.default.join(outDir, "assets");
|
|
11461
11943
|
copyDirRecursive(assetsSrc, assetsDest);
|
|
11462
|
-
const publicDir =
|
|
11944
|
+
const publicDir = import_path14.default.join(projectRoot, "public");
|
|
11463
11945
|
const candidates = ["favicon.ico", "favicon.png"];
|
|
11464
11946
|
for (const name of candidates) {
|
|
11465
|
-
const fromPublic =
|
|
11466
|
-
if (
|
|
11467
|
-
const dest =
|
|
11468
|
-
ensureDir(
|
|
11469
|
-
|
|
11947
|
+
const fromPublic = import_path14.default.join(publicDir, name);
|
|
11948
|
+
if (import_fs12.default.existsSync(fromPublic)) {
|
|
11949
|
+
const dest = import_path14.default.join(outDir, name);
|
|
11950
|
+
ensureDir(import_path14.default.dirname(dest));
|
|
11951
|
+
import_fs12.default.copyFileSync(fromPublic, dest);
|
|
11470
11952
|
break;
|
|
11471
11953
|
}
|
|
11472
11954
|
}
|
|
@@ -11476,10 +11958,10 @@ function getFaviconInfo(projectRoot, staticDir = "public", isDev = false) {
|
|
|
11476
11958
|
{ name: "favicon.ico", type: "image/x-icon" },
|
|
11477
11959
|
{ name: "favicon.png", type: "image/png" }
|
|
11478
11960
|
];
|
|
11479
|
-
const publicDir =
|
|
11961
|
+
const publicDir = import_path14.default.join(projectRoot, staticDir);
|
|
11480
11962
|
for (const candidate of candidates) {
|
|
11481
|
-
const publicPath =
|
|
11482
|
-
if (
|
|
11963
|
+
const publicPath = import_path14.default.join(publicDir, candidate.name);
|
|
11964
|
+
if (import_fs12.default.existsSync(publicPath)) {
|
|
11483
11965
|
return {
|
|
11484
11966
|
path: `/${candidate.name}`,
|
|
11485
11967
|
// Served at root from public/
|
|
@@ -11497,10 +11979,10 @@ function generateAssetManifest(outDir, stats) {
|
|
|
11497
11979
|
},
|
|
11498
11980
|
chunks: {}
|
|
11499
11981
|
};
|
|
11500
|
-
if (!
|
|
11982
|
+
if (!import_fs12.default.existsSync(outDir)) {
|
|
11501
11983
|
return manifest;
|
|
11502
11984
|
}
|
|
11503
|
-
const files =
|
|
11985
|
+
const files = import_fs12.default.readdirSync(outDir);
|
|
11504
11986
|
if (stats) {
|
|
11505
11987
|
try {
|
|
11506
11988
|
const statsJson = stats.toJson({
|
|
@@ -11629,12 +12111,12 @@ function generateAssetManifest(outDir, stats) {
|
|
|
11629
12111
|
}
|
|
11630
12112
|
function loadAssetManifest(projectRoot) {
|
|
11631
12113
|
const { BUILD_FOLDER_NAME: BUILD_FOLDER_NAME2 } = (init_globals(), __toCommonJS(globals_exports));
|
|
11632
|
-
const manifestPath =
|
|
11633
|
-
if (!
|
|
12114
|
+
const manifestPath = import_path14.default.join(projectRoot, BUILD_FOLDER_NAME2, "asset-manifest.json");
|
|
12115
|
+
if (!import_fs12.default.existsSync(manifestPath)) {
|
|
11634
12116
|
return null;
|
|
11635
12117
|
}
|
|
11636
12118
|
try {
|
|
11637
|
-
const manifest = JSON.parse(
|
|
12119
|
+
const manifest = JSON.parse(import_fs12.default.readFileSync(manifestPath, "utf-8"));
|
|
11638
12120
|
return manifest;
|
|
11639
12121
|
} catch (err) {
|
|
11640
12122
|
return null;
|
|
@@ -11657,11 +12139,11 @@ function getClientCssPath(projectRoot) {
|
|
|
11657
12139
|
var import_dotenv = __toESM(require("dotenv"));
|
|
11658
12140
|
init_globals();
|
|
11659
12141
|
function createClientConfig(projectRoot, mode) {
|
|
11660
|
-
const buildDir =
|
|
11661
|
-
const clientEntry =
|
|
11662
|
-
const outDir =
|
|
11663
|
-
const envPath2 =
|
|
11664
|
-
if (
|
|
12142
|
+
const buildDir = import_path15.default.join(projectRoot, BUILD_FOLDER_NAME);
|
|
12143
|
+
const clientEntry = import_path15.default.join(buildDir, "boostrap.ts");
|
|
12144
|
+
const outDir = import_path15.default.join(buildDir, "client");
|
|
12145
|
+
const envPath2 = import_path15.default.join(projectRoot, ".env");
|
|
12146
|
+
if (import_fs13.default.existsSync(envPath2)) {
|
|
11665
12147
|
import_dotenv.default.config({ path: envPath2 });
|
|
11666
12148
|
}
|
|
11667
12149
|
const publicEnv = {};
|
|
@@ -11781,8 +12263,8 @@ function createClientConfig(projectRoot, mode) {
|
|
|
11781
12263
|
}
|
|
11782
12264
|
|
|
11783
12265
|
// modules/build/bundler/client.ts
|
|
11784
|
-
var
|
|
11785
|
-
var
|
|
12266
|
+
var import_path16 = __toESM(require("path"));
|
|
12267
|
+
var import_fs14 = __toESM(require("fs"));
|
|
11786
12268
|
init_globals();
|
|
11787
12269
|
function startClientBundler(projectRoot, mode = "development") {
|
|
11788
12270
|
const { config, outDir } = createClientConfig(projectRoot, mode);
|
|
@@ -11892,18 +12374,18 @@ function buildClientBundle(projectRoot) {
|
|
|
11892
12374
|
}
|
|
11893
12375
|
copyStaticAssets(projectRoot, outDir);
|
|
11894
12376
|
const assetManifest = generateAssetManifest(outDir, stats);
|
|
11895
|
-
const manifestPath =
|
|
11896
|
-
|
|
12377
|
+
const manifestPath = import_path16.default.join(projectRoot, BUILD_FOLDER_NAME, "asset-manifest.json");
|
|
12378
|
+
import_fs14.default.writeFileSync(manifestPath, JSON.stringify(assetManifest, null, 2), "utf-8");
|
|
11897
12379
|
resolve3({ outDir });
|
|
11898
12380
|
});
|
|
11899
12381
|
});
|
|
11900
12382
|
}
|
|
11901
12383
|
|
|
11902
12384
|
// modules/build/ssg/builder.ts
|
|
11903
|
-
var
|
|
12385
|
+
var import_path24 = __toESM(require("path"));
|
|
11904
12386
|
|
|
11905
12387
|
// modules/build/ssg/path.ts
|
|
11906
|
-
var
|
|
12388
|
+
var import_path17 = __toESM(require("path"));
|
|
11907
12389
|
function buildPathFromPattern(pattern, params) {
|
|
11908
12390
|
const segments = pattern.split("/").filter(Boolean);
|
|
11909
12391
|
const parts = [];
|
|
@@ -11932,12 +12414,12 @@ function buildPathFromPattern(pattern, params) {
|
|
|
11932
12414
|
}
|
|
11933
12415
|
function pathToOutDir(baseDir, urlPath) {
|
|
11934
12416
|
const clean = urlPath === "/" ? "" : urlPath.replace(/^\/+/, "");
|
|
11935
|
-
return
|
|
12417
|
+
return import_path17.default.join(baseDir, clean);
|
|
11936
12418
|
}
|
|
11937
12419
|
|
|
11938
12420
|
// modules/build/ssg/renderer.ts
|
|
11939
|
-
var
|
|
11940
|
-
var
|
|
12421
|
+
var import_fs16 = __toESM(require("fs"));
|
|
12422
|
+
var import_path22 = __toESM(require("path"));
|
|
11941
12423
|
var import_server2 = require("react-dom/server");
|
|
11942
12424
|
|
|
11943
12425
|
// modules/rendering/createDocumentTree/index.ts
|
|
@@ -12360,7 +12842,7 @@ init_globals();
|
|
|
12360
12842
|
var import_server = require("react-dom/server");
|
|
12361
12843
|
|
|
12362
12844
|
// modules/server/handlers/middleware.ts
|
|
12363
|
-
var
|
|
12845
|
+
var import_path18 = __toESM(require("path"));
|
|
12364
12846
|
|
|
12365
12847
|
// modules/logger/index.ts
|
|
12366
12848
|
var import_pino = __toESM(require("pino"));
|
|
@@ -12492,12 +12974,12 @@ var DEFAULT_IGNORED_PATHS = [
|
|
|
12492
12974
|
/^\/sockjs-node/
|
|
12493
12975
|
// Hot reload websocket
|
|
12494
12976
|
];
|
|
12495
|
-
function shouldIgnorePath(
|
|
12977
|
+
function shouldIgnorePath(path31, ignoredPaths) {
|
|
12496
12978
|
return ignoredPaths.some((pattern) => {
|
|
12497
12979
|
if (typeof pattern === "string") {
|
|
12498
|
-
return
|
|
12980
|
+
return path31 === pattern || path31.startsWith(pattern);
|
|
12499
12981
|
}
|
|
12500
|
-
return pattern.test(
|
|
12982
|
+
return pattern.test(path31);
|
|
12501
12983
|
});
|
|
12502
12984
|
}
|
|
12503
12985
|
function requestLoggerMiddleware(options = {}) {
|
|
@@ -12559,7 +13041,7 @@ async function runRouteMiddlewares(route, ctx) {
|
|
|
12559
13041
|
);
|
|
12560
13042
|
} catch (error) {
|
|
12561
13043
|
const reqLogger = getRequestLogger(ctx.req);
|
|
12562
|
-
const relativePath = route.pageFile ?
|
|
13044
|
+
const relativePath = route.pageFile ? import_path18.default.relative(process.cwd(), route.pageFile) : route.pattern;
|
|
12563
13045
|
reqLogger.error("Route middleware failed", error instanceof Error ? error : new Error(String(error)), {
|
|
12564
13046
|
route: route.pattern,
|
|
12565
13047
|
middlewareIndex: i,
|
|
@@ -12574,7 +13056,7 @@ async function runRouteMiddlewares(route, ctx) {
|
|
|
12574
13056
|
}
|
|
12575
13057
|
|
|
12576
13058
|
// modules/server/handlers/server-hook.ts
|
|
12577
|
-
var
|
|
13059
|
+
var import_path19 = __toESM(require("path"));
|
|
12578
13060
|
function createServerHookErrorMessage(error, hookType, routePattern, filePath) {
|
|
12579
13061
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
12580
13062
|
const errorStack = error instanceof Error ? error.stack : void 0;
|
|
@@ -12583,7 +13065,7 @@ function createServerHookErrorMessage(error, hookType, routePattern, filePath) {
|
|
|
12583
13065
|
message += `Route: ${routePattern}
|
|
12584
13066
|
`;
|
|
12585
13067
|
if (filePath) {
|
|
12586
|
-
const relativePath =
|
|
13068
|
+
const relativePath = import_path19.default.relative(process.cwd(), filePath);
|
|
12587
13069
|
message += `File: ${relativePath}
|
|
12588
13070
|
`;
|
|
12589
13071
|
}
|
|
@@ -12644,7 +13126,9 @@ function handleDataResponse(res, loaderResult, theme, layoutProps, pageProps, er
|
|
|
12644
13126
|
// Combined props for backward compatibility
|
|
12645
13127
|
props: loaderResult.props ?? {},
|
|
12646
13128
|
metadata: loaderResult.metadata ?? null,
|
|
12647
|
-
theme: loaderResult.theme ?? theme ?? null
|
|
13129
|
+
theme: loaderResult.theme ?? theme ?? null,
|
|
13130
|
+
// Include pathname if provided (for rewrites - client needs to know the rewritten path)
|
|
13131
|
+
...loaderResult.pathname ? { pathname: loaderResult.pathname } : {}
|
|
12648
13132
|
};
|
|
12649
13133
|
if (layoutProps !== void 0 && layoutProps !== null) {
|
|
12650
13134
|
response.layoutProps = layoutProps;
|
|
@@ -12676,24 +13160,24 @@ function handleNotFound(res, urlPath) {
|
|
|
12676
13160
|
}
|
|
12677
13161
|
|
|
12678
13162
|
// modules/server/handlers/ssg.ts
|
|
12679
|
-
var
|
|
12680
|
-
var
|
|
13163
|
+
var import_fs15 = __toESM(require("fs"));
|
|
13164
|
+
var import_path20 = __toESM(require("path"));
|
|
12681
13165
|
var logger2 = createModuleLogger("ssg");
|
|
12682
13166
|
function getSsgDirForPath(baseDir, urlPath) {
|
|
12683
13167
|
const clean = urlPath === "/" ? "" : urlPath.replace(/^\/+/, "");
|
|
12684
|
-
return
|
|
13168
|
+
return import_path20.default.join(baseDir, clean);
|
|
12685
13169
|
}
|
|
12686
13170
|
function getSsgHtmlPath(baseDir, urlPath) {
|
|
12687
13171
|
const dir = getSsgDirForPath(baseDir, urlPath);
|
|
12688
|
-
return
|
|
13172
|
+
return import_path20.default.join(dir, "index.html");
|
|
12689
13173
|
}
|
|
12690
13174
|
function getSsgDataPath(baseDir, urlPath) {
|
|
12691
13175
|
const dir = getSsgDirForPath(baseDir, urlPath);
|
|
12692
|
-
return
|
|
13176
|
+
return import_path20.default.join(dir, "data.json");
|
|
12693
13177
|
}
|
|
12694
13178
|
function tryServeSsgHtml(res, ssgOutDir, urlPath) {
|
|
12695
13179
|
const ssgHtmlPath = getSsgHtmlPath(ssgOutDir, urlPath);
|
|
12696
|
-
if (!
|
|
13180
|
+
if (!import_fs15.default.existsSync(ssgHtmlPath)) {
|
|
12697
13181
|
return false;
|
|
12698
13182
|
}
|
|
12699
13183
|
logger2.info("Serving SSG HTML", { urlPath, ssgHtmlPath });
|
|
@@ -12703,17 +13187,17 @@ function tryServeSsgHtml(res, ssgOutDir, urlPath) {
|
|
|
12703
13187
|
);
|
|
12704
13188
|
res.statusCode = 200;
|
|
12705
13189
|
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
12706
|
-
const stream =
|
|
13190
|
+
const stream = import_fs15.default.createReadStream(ssgHtmlPath, { encoding: "utf-8" });
|
|
12707
13191
|
stream.pipe(res);
|
|
12708
13192
|
return true;
|
|
12709
13193
|
}
|
|
12710
13194
|
function tryServeSsgData(res, ssgOutDir, urlPath) {
|
|
12711
13195
|
const ssgDataPath = getSsgDataPath(ssgOutDir, urlPath);
|
|
12712
|
-
if (!
|
|
13196
|
+
if (!import_fs15.default.existsSync(ssgDataPath)) {
|
|
12713
13197
|
return false;
|
|
12714
13198
|
}
|
|
12715
13199
|
try {
|
|
12716
|
-
const raw =
|
|
13200
|
+
const raw = import_fs15.default.readFileSync(ssgDataPath, "utf-8");
|
|
12717
13201
|
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
12718
13202
|
res.status(200).end(raw);
|
|
12719
13203
|
return true;
|
|
@@ -12779,7 +13263,7 @@ function sanitizeQuery(query) {
|
|
|
12779
13263
|
}
|
|
12780
13264
|
|
|
12781
13265
|
// modules/server/handlers/pages.ts
|
|
12782
|
-
var
|
|
13266
|
+
var import_path21 = __toESM(require("path"));
|
|
12783
13267
|
function mergeMetadata(base, override) {
|
|
12784
13268
|
if (!base && !override) return null;
|
|
12785
13269
|
if (!base) return override;
|
|
@@ -12846,8 +13330,43 @@ async function handlePageRequestInternal(options) {
|
|
|
12846
13330
|
ssgOutDir,
|
|
12847
13331
|
theme,
|
|
12848
13332
|
projectRoot,
|
|
12849
|
-
config
|
|
13333
|
+
config,
|
|
13334
|
+
rewriteLoader
|
|
12850
13335
|
} = options;
|
|
13336
|
+
let finalUrlPath = urlPath;
|
|
13337
|
+
let extractedParams = {};
|
|
13338
|
+
if (rewriteLoader) {
|
|
13339
|
+
try {
|
|
13340
|
+
const compiledRewrites = await rewriteLoader.loadRewrites();
|
|
13341
|
+
const rewriteResult = await processRewrites(urlPath, compiledRewrites, req);
|
|
13342
|
+
if (rewriteResult) {
|
|
13343
|
+
finalUrlPath = rewriteResult.rewrittenPath;
|
|
13344
|
+
extractedParams = rewriteResult.extractedParams;
|
|
13345
|
+
finalUrlPath = finalUrlPath.replace(/\/+/g, "/").replace(/^([^/])/, "/$1").replace(/\/$/, "") || "/";
|
|
13346
|
+
if (env === "dev") {
|
|
13347
|
+
const reqLogger2 = getRequestLogger(req);
|
|
13348
|
+
reqLogger2.debug("Rewrite applied", {
|
|
13349
|
+
originalPath: urlPath,
|
|
13350
|
+
rewrittenPath: finalUrlPath,
|
|
13351
|
+
extractedParams,
|
|
13352
|
+
host: req.get("host")
|
|
13353
|
+
});
|
|
13354
|
+
}
|
|
13355
|
+
Object.assign(req.query, extractedParams);
|
|
13356
|
+
if (!req.locals) {
|
|
13357
|
+
req.locals = {};
|
|
13358
|
+
}
|
|
13359
|
+
Object.assign(req.locals, extractedParams);
|
|
13360
|
+
}
|
|
13361
|
+
} catch (error) {
|
|
13362
|
+
const reqLogger2 = getRequestLogger(req);
|
|
13363
|
+
reqLogger2.error("Error processing rewrites", error, {
|
|
13364
|
+
urlPath,
|
|
13365
|
+
host: req.get("host")
|
|
13366
|
+
});
|
|
13367
|
+
}
|
|
13368
|
+
}
|
|
13369
|
+
finalUrlPath = finalUrlPath.replace(/\/$/, "") || "/";
|
|
12851
13370
|
const clientJsPath = env === "dev" ? "/static/client.js" : projectRoot ? getClientJsPath(projectRoot) : "/static/client.js";
|
|
12852
13371
|
const clientCssPath = env === "dev" ? "/static/client.css" : projectRoot ? getClientCssPath(projectRoot) : "/static/client.css";
|
|
12853
13372
|
const assetManifest = env === "prod" && projectRoot ? loadAssetManifest(projectRoot) : null;
|
|
@@ -12856,18 +13375,43 @@ async function handlePageRequestInternal(options) {
|
|
|
12856
13375
|
const skipLayoutHooks = isDataReq && req.headers["x-skip-layout-hooks"] === "true";
|
|
12857
13376
|
if (env === "prod" && ssgOutDir) {
|
|
12858
13377
|
if (isDataReq) {
|
|
12859
|
-
if (tryServeSsgData(res, ssgOutDir,
|
|
13378
|
+
if (tryServeSsgData(res, ssgOutDir, finalUrlPath)) {
|
|
12860
13379
|
return;
|
|
12861
13380
|
}
|
|
12862
13381
|
} else {
|
|
12863
|
-
if (tryServeSsgHtml(res, ssgOutDir,
|
|
13382
|
+
if (tryServeSsgHtml(res, ssgOutDir, finalUrlPath)) {
|
|
12864
13383
|
return;
|
|
12865
13384
|
}
|
|
12866
13385
|
}
|
|
12867
13386
|
}
|
|
12868
|
-
const matched = matchRoute(routes,
|
|
13387
|
+
const matched = matchRoute(routes, finalUrlPath);
|
|
13388
|
+
if (env === "dev") {
|
|
13389
|
+
const reqLogger2 = getRequestLogger(req);
|
|
13390
|
+
if (finalUrlPath !== urlPath) {
|
|
13391
|
+
reqLogger2.debug("Route matching after rewrite", {
|
|
13392
|
+
originalPath: urlPath,
|
|
13393
|
+
rewrittenPath: finalUrlPath,
|
|
13394
|
+
matched: !!matched,
|
|
13395
|
+
matchedRoute: matched?.route.pattern,
|
|
13396
|
+
matchedParams: matched?.params,
|
|
13397
|
+
availableRoutes: routes.slice(0, 10).map((r) => r.pattern)
|
|
13398
|
+
// Show first 10 routes
|
|
13399
|
+
});
|
|
13400
|
+
} else if (!matched) {
|
|
13401
|
+
reqLogger2.debug("No route match found", {
|
|
13402
|
+
path: finalUrlPath,
|
|
13403
|
+
availableRoutes: routes.slice(0, 10).map((r) => r.pattern)
|
|
13404
|
+
});
|
|
13405
|
+
}
|
|
13406
|
+
}
|
|
12869
13407
|
const routerData = buildRouterData(req);
|
|
12870
13408
|
if (!matched) {
|
|
13409
|
+
if (isDataReq) {
|
|
13410
|
+
res.statusCode = 404;
|
|
13411
|
+
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
13412
|
+
res.end(JSON.stringify({ notFound: true, pathname: finalUrlPath }));
|
|
13413
|
+
return;
|
|
13414
|
+
}
|
|
12871
13415
|
if (notFoundPage) {
|
|
12872
13416
|
const ctx2 = {
|
|
12873
13417
|
req,
|
|
@@ -12891,7 +13435,7 @@ async function handlePageRequestInternal(options) {
|
|
|
12891
13435
|
} catch (error) {
|
|
12892
13436
|
const reqLogger2 = getRequestLogger(req);
|
|
12893
13437
|
const layoutFile = notFoundPage.layoutFiles[i];
|
|
12894
|
-
const relativeLayoutPath = layoutFile ?
|
|
13438
|
+
const relativeLayoutPath = layoutFile ? import_path21.default.relative(projectRoot || process.cwd(), layoutFile) : "unknown";
|
|
12895
13439
|
reqLogger2.error("Layout middleware failed for not-found page", error instanceof Error ? error : new Error(String(error)), {
|
|
12896
13440
|
layoutIndex: i,
|
|
12897
13441
|
layoutFile: relativeLayoutPath
|
|
@@ -12912,7 +13456,7 @@ async function handlePageRequestInternal(options) {
|
|
|
12912
13456
|
} catch (error) {
|
|
12913
13457
|
const reqLogger2 = getRequestLogger(req);
|
|
12914
13458
|
const layoutFile = notFoundPage.layoutFiles[i];
|
|
12915
|
-
const relativeLayoutPath = layoutFile ?
|
|
13459
|
+
const relativeLayoutPath = layoutFile ? import_path21.default.relative(projectRoot || process.cwd(), layoutFile) : "unknown";
|
|
12916
13460
|
reqLogger2.warn("Layout server hook failed for not-found page", {
|
|
12917
13461
|
error: error instanceof Error ? error.message : String(error),
|
|
12918
13462
|
stack: error instanceof Error ? error.stack : void 0,
|
|
@@ -12946,7 +13490,7 @@ async function handlePageRequestInternal(options) {
|
|
|
12946
13490
|
);
|
|
12947
13491
|
return;
|
|
12948
13492
|
}
|
|
12949
|
-
const initialData2 = buildInitialData(
|
|
13493
|
+
const initialData2 = buildInitialData(finalUrlPath, {}, combinedLoaderResult2);
|
|
12950
13494
|
const appTree2 = buildAppTree(notFoundPage, {}, initialData2.props);
|
|
12951
13495
|
initialData2.notFound = true;
|
|
12952
13496
|
const nonce2 = res.locals.nonce || void 0;
|
|
@@ -13032,7 +13576,7 @@ async function handlePageRequestInternal(options) {
|
|
|
13032
13576
|
);
|
|
13033
13577
|
} catch (error) {
|
|
13034
13578
|
const layoutFile = route.layoutFiles[i];
|
|
13035
|
-
const relativeLayoutPath = layoutFile ?
|
|
13579
|
+
const relativeLayoutPath = layoutFile ? import_path21.default.relative(projectRoot || process.cwd(), layoutFile) : "unknown";
|
|
13036
13580
|
reqLogger.error("Layout middleware failed", error instanceof Error ? error : new Error(String(error)), {
|
|
13037
13581
|
route: route.pattern,
|
|
13038
13582
|
layoutIndex: i,
|
|
@@ -13056,7 +13600,7 @@ async function handlePageRequestInternal(options) {
|
|
|
13056
13600
|
}
|
|
13057
13601
|
} catch (error) {
|
|
13058
13602
|
const layoutFile = route.layoutFiles[i];
|
|
13059
|
-
const relativeLayoutPath = layoutFile ?
|
|
13603
|
+
const relativeLayoutPath = layoutFile ? import_path21.default.relative(projectRoot || process.cwd(), layoutFile) : "unknown";
|
|
13060
13604
|
reqLogger.warn("Layout server hook failed", {
|
|
13061
13605
|
error: error instanceof Error ? error.message : String(error),
|
|
13062
13606
|
stack: error instanceof Error ? error.stack : void 0,
|
|
@@ -13076,7 +13620,7 @@ async function handlePageRequestInternal(options) {
|
|
|
13076
13620
|
loaderResult.theme = theme;
|
|
13077
13621
|
}
|
|
13078
13622
|
} catch (error) {
|
|
13079
|
-
const relativePagePath = route.pageFile ?
|
|
13623
|
+
const relativePagePath = route.pageFile ? import_path21.default.relative(projectRoot || process.cwd(), route.pageFile) : "unknown";
|
|
13080
13624
|
reqLogger.error("Page server hook failed", {
|
|
13081
13625
|
error: error instanceof Error ? error.message : String(error),
|
|
13082
13626
|
stack: error instanceof Error ? error.stack : void 0,
|
|
@@ -13123,7 +13667,9 @@ async function handlePageRequestInternal(options) {
|
|
|
13123
13667
|
const combinedLoaderResult = {
|
|
13124
13668
|
...loaderResult,
|
|
13125
13669
|
props: combinedProps,
|
|
13126
|
-
metadata: combinedMetadata
|
|
13670
|
+
metadata: combinedMetadata,
|
|
13671
|
+
pathname: finalUrlPath
|
|
13672
|
+
// Include rewritten pathname for client-side matching
|
|
13127
13673
|
};
|
|
13128
13674
|
if (isDataReq) {
|
|
13129
13675
|
const pagePropsOnly = loaderResult.props || {};
|
|
@@ -13148,7 +13694,7 @@ async function handlePageRequestInternal(options) {
|
|
|
13148
13694
|
}
|
|
13149
13695
|
return;
|
|
13150
13696
|
}
|
|
13151
|
-
const initialData = buildInitialData(
|
|
13697
|
+
const initialData = buildInitialData(finalUrlPath, params, combinedLoaderResult);
|
|
13152
13698
|
const appTree = buildAppTree(route, params, initialData.props);
|
|
13153
13699
|
const chunkName = routeChunks[route.pattern];
|
|
13154
13700
|
let chunkHref = null;
|
|
@@ -13253,7 +13799,7 @@ async function renderErrorPageWithStream(errorPage, req, res, error, routeChunks
|
|
|
13253
13799
|
);
|
|
13254
13800
|
} catch (error2) {
|
|
13255
13801
|
const layoutFile = errorPage.layoutFiles[i];
|
|
13256
|
-
const relativeLayoutPath = layoutFile ?
|
|
13802
|
+
const relativeLayoutPath = layoutFile ? import_path21.default.relative(projectRoot || process.cwd(), layoutFile) : "unknown";
|
|
13257
13803
|
reqLogger.error("Layout middleware failed for error page", error2 instanceof Error ? error2 : new Error(String(error2)), {
|
|
13258
13804
|
layoutIndex: i,
|
|
13259
13805
|
layoutFile: relativeLayoutPath
|
|
@@ -13273,7 +13819,7 @@ async function renderErrorPageWithStream(errorPage, req, res, error, routeChunks
|
|
|
13273
13819
|
}
|
|
13274
13820
|
} catch (err) {
|
|
13275
13821
|
const layoutFile = errorPage.layoutFiles[i];
|
|
13276
|
-
const relativeLayoutPath = layoutFile ?
|
|
13822
|
+
const relativeLayoutPath = layoutFile ? import_path21.default.relative(projectRoot || process.cwd(), layoutFile) : "unknown";
|
|
13277
13823
|
reqLogger.warn("Layout server hook failed for error page", {
|
|
13278
13824
|
error: err instanceof Error ? err.message : String(err),
|
|
13279
13825
|
stack: err instanceof Error ? err.stack : void 0,
|
|
@@ -13510,16 +14056,16 @@ async function renderStaticRoute(projectRoot, ssgOutDir, route, urlPath, params,
|
|
|
13510
14056
|
const html = "<!DOCTYPE html>" + (0, import_server2.renderToString)(documentTree);
|
|
13511
14057
|
const dir = pathToOutDir(ssgOutDir, urlPath);
|
|
13512
14058
|
ensureDir(dir);
|
|
13513
|
-
const htmlFile =
|
|
13514
|
-
const dataFile =
|
|
13515
|
-
|
|
13516
|
-
|
|
14059
|
+
const htmlFile = import_path22.default.join(dir, "index.html");
|
|
14060
|
+
const dataFile = import_path22.default.join(dir, "data.json");
|
|
14061
|
+
import_fs16.default.writeFileSync(htmlFile, html, "utf-8");
|
|
14062
|
+
import_fs16.default.writeFileSync(dataFile, JSON.stringify(initialData, null, 2), "utf-8");
|
|
13517
14063
|
}
|
|
13518
14064
|
|
|
13519
14065
|
// modules/build/ssg/builder.ts
|
|
13520
14066
|
init_globals();
|
|
13521
14067
|
async function buildStaticPages(projectRoot, routes, config) {
|
|
13522
|
-
const ssgOutDir =
|
|
14068
|
+
const ssgOutDir = import_path24.default.join(projectRoot, BUILD_FOLDER_NAME, "ssg");
|
|
13523
14069
|
ensureDir(ssgOutDir);
|
|
13524
14070
|
for (const route of routes) {
|
|
13525
14071
|
if (route.dynamic !== "force-static") continue;
|
|
@@ -13574,27 +14120,27 @@ async function buildStaticPages(projectRoot, routes, config) {
|
|
|
13574
14120
|
}
|
|
13575
14121
|
|
|
13576
14122
|
// modules/build/bundler/server.ts
|
|
13577
|
-
var
|
|
13578
|
-
var
|
|
14123
|
+
var import_path27 = __toESM(require("path"));
|
|
14124
|
+
var import_fs18 = __toESM(require("fs"));
|
|
13579
14125
|
var import_esbuild = __toESM(require("esbuild"));
|
|
13580
14126
|
|
|
13581
14127
|
// modules/server/utils/server-dir.ts
|
|
13582
|
-
var
|
|
13583
|
-
var
|
|
14128
|
+
var import_fs17 = __toESM(require("fs"));
|
|
14129
|
+
var import_path26 = __toESM(require("path"));
|
|
13584
14130
|
init_globals();
|
|
13585
14131
|
var getServerFile = async (projectRoot, fileName) => {
|
|
13586
|
-
const fileTS =
|
|
13587
|
-
const fileJS =
|
|
14132
|
+
const fileTS = import_path26.default.join(projectRoot, `${fileName}.ts`);
|
|
14133
|
+
const fileJS = import_path26.default.join(projectRoot, BUILD_FOLDER_NAME, "server", `${fileName}.js`);
|
|
13588
14134
|
const isDev = process.env.NODE_ENV === "development";
|
|
13589
14135
|
let mod = null;
|
|
13590
14136
|
if (isDev) {
|
|
13591
|
-
if (!
|
|
14137
|
+
if (!import_fs17.default.existsSync(fileTS)) {
|
|
13592
14138
|
return null;
|
|
13593
14139
|
}
|
|
13594
14140
|
require("tsx/cjs");
|
|
13595
14141
|
mod = require(fileTS);
|
|
13596
14142
|
} else {
|
|
13597
|
-
if (!
|
|
14143
|
+
if (!import_fs17.default.existsSync(fileJS)) {
|
|
13598
14144
|
return null;
|
|
13599
14145
|
}
|
|
13600
14146
|
mod = require(fileJS);
|
|
@@ -13776,29 +14322,29 @@ init_globals();
|
|
|
13776
14322
|
var SERVER_FILES = [INIT_FILE_NAME, CONFIG_FILE_NAME];
|
|
13777
14323
|
function createPathAliasPlugin(projectRoot, outDir) {
|
|
13778
14324
|
const aliases = loadAliasesFromTsconfig(projectRoot);
|
|
13779
|
-
const tsconfigPath =
|
|
14325
|
+
const tsconfigPath = import_path27.default.join(projectRoot, "tsconfig.json");
|
|
13780
14326
|
let baseUrl = ".";
|
|
13781
|
-
if (
|
|
14327
|
+
if (import_fs18.default.existsSync(tsconfigPath)) {
|
|
13782
14328
|
try {
|
|
13783
|
-
const tsconfig = JSON.parse(
|
|
14329
|
+
const tsconfig = JSON.parse(import_fs18.default.readFileSync(tsconfigPath, "utf-8"));
|
|
13784
14330
|
baseUrl = tsconfig.compilerOptions?.baseUrl ?? ".";
|
|
13785
14331
|
} catch {
|
|
13786
14332
|
}
|
|
13787
14333
|
}
|
|
13788
14334
|
function resolveAliasToRelative(importPath, sourceFile) {
|
|
13789
|
-
if (importPath.startsWith(".") || importPath.startsWith("/") ||
|
|
14335
|
+
if (importPath.startsWith(".") || importPath.startsWith("/") || import_path27.default.isAbsolute(importPath) || importPath.includes("node_modules")) {
|
|
13790
14336
|
return null;
|
|
13791
14337
|
}
|
|
13792
14338
|
for (const [aliasKey, aliasPath] of Object.entries(aliases)) {
|
|
13793
14339
|
if (importPath.startsWith(aliasKey + "/") || importPath === aliasKey) {
|
|
13794
14340
|
const restPath = importPath.startsWith(aliasKey + "/") ? importPath.slice(aliasKey.length + 1) : "";
|
|
13795
|
-
const resolvedPath = restPath ?
|
|
14341
|
+
const resolvedPath = restPath ? import_path27.default.join(aliasPath, restPath) : aliasPath;
|
|
13796
14342
|
let actualPath = null;
|
|
13797
14343
|
const extensions = [".ts", ".tsx", ".js", ".jsx", ".json"];
|
|
13798
|
-
if (
|
|
14344
|
+
if (import_fs18.default.existsSync(resolvedPath) && import_fs18.default.statSync(resolvedPath).isDirectory()) {
|
|
13799
14345
|
for (const ext of extensions) {
|
|
13800
|
-
const indexPath =
|
|
13801
|
-
if (
|
|
14346
|
+
const indexPath = import_path27.default.join(resolvedPath, `index${ext}`);
|
|
14347
|
+
if (import_fs18.default.existsSync(indexPath)) {
|
|
13802
14348
|
actualPath = indexPath;
|
|
13803
14349
|
break;
|
|
13804
14350
|
}
|
|
@@ -13806,20 +14352,20 @@ function createPathAliasPlugin(projectRoot, outDir) {
|
|
|
13806
14352
|
} else {
|
|
13807
14353
|
for (const ext of extensions) {
|
|
13808
14354
|
const filePath = resolvedPath + ext;
|
|
13809
|
-
if (
|
|
14355
|
+
if (import_fs18.default.existsSync(filePath)) {
|
|
13810
14356
|
actualPath = filePath;
|
|
13811
14357
|
break;
|
|
13812
14358
|
}
|
|
13813
14359
|
}
|
|
13814
|
-
if (!actualPath &&
|
|
14360
|
+
if (!actualPath && import_fs18.default.existsSync(resolvedPath)) {
|
|
13815
14361
|
actualPath = resolvedPath;
|
|
13816
14362
|
}
|
|
13817
14363
|
}
|
|
13818
14364
|
if (actualPath) {
|
|
13819
|
-
const relativePath =
|
|
14365
|
+
const relativePath = import_path27.default.relative(outDir, actualPath);
|
|
13820
14366
|
const normalizedPath = relativePath.replace(/\\/g, "/");
|
|
13821
14367
|
const finalPath = normalizedPath.startsWith(".") ? normalizedPath : `./${normalizedPath}`;
|
|
13822
|
-
const ext =
|
|
14368
|
+
const ext = import_path27.default.extname(finalPath);
|
|
13823
14369
|
const pathWithoutExt = ext === ".json" ? finalPath : finalPath.slice(0, -ext.length);
|
|
13824
14370
|
return pathWithoutExt;
|
|
13825
14371
|
}
|
|
@@ -13831,13 +14377,13 @@ function createPathAliasPlugin(projectRoot, outDir) {
|
|
|
13831
14377
|
name: "path-alias-resolver",
|
|
13832
14378
|
setup(build) {
|
|
13833
14379
|
build.onLoad({ filter: /\.(ts|tsx|js|jsx)$/ }, (args) => {
|
|
13834
|
-
const fileName =
|
|
14380
|
+
const fileName = import_path27.default.basename(args.path);
|
|
13835
14381
|
const isServerFile = SERVER_FILES.some((f) => fileName === `${f}.ts` || fileName === `${f}.tsx` || fileName === `${f}.js` || fileName === `${f}.jsx`);
|
|
13836
|
-
const isInProjectRoot =
|
|
14382
|
+
const isInProjectRoot = import_path27.default.dirname(args.path) === projectRoot;
|
|
13837
14383
|
if (!isServerFile || !isInProjectRoot) {
|
|
13838
14384
|
return null;
|
|
13839
14385
|
}
|
|
13840
|
-
const contents =
|
|
14386
|
+
const contents = import_fs18.default.readFileSync(args.path, "utf-8");
|
|
13841
14387
|
let transformed = contents;
|
|
13842
14388
|
const aliasPatterns = Object.keys(aliases).sort((a, b) => b.length - a.length);
|
|
13843
14389
|
for (const aliasKey of aliasPatterns) {
|
|
@@ -13857,7 +14403,7 @@ function createPathAliasPlugin(projectRoot, outDir) {
|
|
|
13857
14403
|
}
|
|
13858
14404
|
return {
|
|
13859
14405
|
contents: transformed,
|
|
13860
|
-
loader:
|
|
14406
|
+
loader: import_path27.default.extname(args.path).slice(1)
|
|
13861
14407
|
};
|
|
13862
14408
|
});
|
|
13863
14409
|
build.onResolve({ filter: /.*/ }, (args) => {
|
|
@@ -13876,9 +14422,9 @@ function createPathAliasPlugin(projectRoot, outDir) {
|
|
|
13876
14422
|
function collectAppSources(appDir) {
|
|
13877
14423
|
const entries = [];
|
|
13878
14424
|
function walk(dir) {
|
|
13879
|
-
const items =
|
|
14425
|
+
const items = import_fs18.default.readdirSync(dir, { withFileTypes: true });
|
|
13880
14426
|
for (const item of items) {
|
|
13881
|
-
const full =
|
|
14427
|
+
const full = import_path27.default.join(dir, item.name);
|
|
13882
14428
|
if (item.isDirectory()) {
|
|
13883
14429
|
walk(full);
|
|
13884
14430
|
continue;
|
|
@@ -13895,7 +14441,7 @@ function collectAppSources(appDir) {
|
|
|
13895
14441
|
return entries;
|
|
13896
14442
|
}
|
|
13897
14443
|
async function buildServerApp(projectRoot, appDir) {
|
|
13898
|
-
const outDir =
|
|
14444
|
+
const outDir = import_path27.default.join(projectRoot, BUILD_FOLDER_NAME, "server");
|
|
13899
14445
|
const entryPoints = collectAppSources(appDir);
|
|
13900
14446
|
ensureDir(outDir);
|
|
13901
14447
|
if (entryPoints.length === 0) {
|
|
@@ -13913,14 +14459,14 @@ async function buildServerApp(projectRoot, appDir) {
|
|
|
13913
14459
|
bundle: true,
|
|
13914
14460
|
splitting: false,
|
|
13915
14461
|
logLevel: "info",
|
|
13916
|
-
tsconfig:
|
|
14462
|
+
tsconfig: import_path27.default.join(projectRoot, "tsconfig.json"),
|
|
13917
14463
|
packages: "external"
|
|
13918
14464
|
});
|
|
13919
14465
|
const pathAliasPlugin = createPathAliasPlugin(projectRoot, outDir);
|
|
13920
14466
|
for (const fileName of SERVER_FILES) {
|
|
13921
|
-
const initTS =
|
|
13922
|
-
const initJS =
|
|
13923
|
-
if (
|
|
14467
|
+
const initTS = import_path27.default.join(projectRoot, `${fileName}.ts`);
|
|
14468
|
+
const initJS = import_path27.default.join(outDir, `${fileName}.js`);
|
|
14469
|
+
if (import_fs18.default.existsSync(initTS)) {
|
|
13924
14470
|
await import_esbuild.default.build({
|
|
13925
14471
|
entryPoints: [initTS],
|
|
13926
14472
|
outfile: initJS,
|
|
@@ -13931,7 +14477,7 @@ async function buildServerApp(projectRoot, appDir) {
|
|
|
13931
14477
|
sourcemap: true,
|
|
13932
14478
|
bundle: false,
|
|
13933
14479
|
logLevel: "info",
|
|
13934
|
-
tsconfig:
|
|
14480
|
+
tsconfig: import_path27.default.join(projectRoot, "tsconfig.json"),
|
|
13935
14481
|
plugins: [pathAliasPlugin]
|
|
13936
14482
|
});
|
|
13937
14483
|
}
|
|
@@ -13943,8 +14489,8 @@ async function buildServerApp(projectRoot, appDir) {
|
|
|
13943
14489
|
init_globals();
|
|
13944
14490
|
|
|
13945
14491
|
// src/config.ts
|
|
13946
|
-
var
|
|
13947
|
-
var
|
|
14492
|
+
var import_path28 = __toESM(require("path"));
|
|
14493
|
+
var import_fs19 = __toESM(require("fs"));
|
|
13948
14494
|
init_globals();
|
|
13949
14495
|
var DEFAULT_CONFIG2 = {
|
|
13950
14496
|
directories: {
|
|
@@ -14011,8 +14557,8 @@ function validateConfig(config, projectRoot) {
|
|
|
14011
14557
|
if (!config.directories.app || typeof config.directories.app !== "string") {
|
|
14012
14558
|
errors.push("config.directories.app must be a non-empty string");
|
|
14013
14559
|
} else {
|
|
14014
|
-
const appDir =
|
|
14015
|
-
if (!
|
|
14560
|
+
const appDir = import_path28.default.join(projectRoot, config.directories.app);
|
|
14561
|
+
if (!import_fs19.default.existsSync(appDir) && process.env.NODE_ENV !== "test") {
|
|
14016
14562
|
errors.push(
|
|
14017
14563
|
`App directory not found: ${config.directories.app}
|
|
14018
14564
|
Expected at: ${appDir}
|
|
@@ -14116,17 +14662,17 @@ function validateConfig(config, projectRoot) {
|
|
|
14116
14662
|
}
|
|
14117
14663
|
function loadConfig(projectRoot) {
|
|
14118
14664
|
const configFiles = [
|
|
14119
|
-
|
|
14120
|
-
|
|
14121
|
-
|
|
14665
|
+
import_path28.default.join(projectRoot, "loly.config.ts"),
|
|
14666
|
+
import_path28.default.join(projectRoot, "loly.config.js"),
|
|
14667
|
+
import_path28.default.join(projectRoot, "loly.config.json")
|
|
14122
14668
|
];
|
|
14123
14669
|
let userConfig = {};
|
|
14124
14670
|
let loadedConfigFile = null;
|
|
14125
14671
|
for (const configFile of configFiles) {
|
|
14126
|
-
if (
|
|
14672
|
+
if (import_fs19.default.existsSync(configFile)) {
|
|
14127
14673
|
try {
|
|
14128
14674
|
if (configFile.endsWith(".json")) {
|
|
14129
|
-
const content =
|
|
14675
|
+
const content = import_fs19.default.readFileSync(configFile, "utf-8");
|
|
14130
14676
|
userConfig = JSON.parse(content);
|
|
14131
14677
|
} else {
|
|
14132
14678
|
if (process.env.NODE_ENV === "development") {
|
|
@@ -14135,12 +14681,12 @@ function loadConfig(projectRoot) {
|
|
|
14135
14681
|
const mod = require(configFile);
|
|
14136
14682
|
userConfig = typeof mod.default === "function" ? mod.default(process.env.NODE_ENV) : mod.default || mod.config || mod;
|
|
14137
14683
|
}
|
|
14138
|
-
loadedConfigFile =
|
|
14684
|
+
loadedConfigFile = import_path28.default.relative(projectRoot, configFile);
|
|
14139
14685
|
break;
|
|
14140
14686
|
} catch (error) {
|
|
14141
14687
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
14142
14688
|
throw new ConfigValidationError(
|
|
14143
|
-
`Failed to load configuration from ${
|
|
14689
|
+
`Failed to load configuration from ${import_path28.default.relative(projectRoot, configFile)}:
|
|
14144
14690
|
${errorMessage}
|
|
14145
14691
|
\u{1F4A1} Suggestion: Check that your config file exports a valid configuration object`
|
|
14146
14692
|
);
|
|
@@ -14164,13 +14710,13 @@ ${error.message}`;
|
|
|
14164
14710
|
return config;
|
|
14165
14711
|
}
|
|
14166
14712
|
function getAppDir(projectRoot, config) {
|
|
14167
|
-
return
|
|
14713
|
+
return import_path28.default.resolve(projectRoot, config.directories.app);
|
|
14168
14714
|
}
|
|
14169
14715
|
function getBuildDir(projectRoot, config) {
|
|
14170
|
-
return
|
|
14716
|
+
return import_path28.default.join(projectRoot, config.directories.build);
|
|
14171
14717
|
}
|
|
14172
14718
|
function getStaticDir(projectRoot, config) {
|
|
14173
|
-
return
|
|
14719
|
+
return import_path28.default.resolve(projectRoot, config.directories.static);
|
|
14174
14720
|
}
|
|
14175
14721
|
|
|
14176
14722
|
// modules/build/index.ts
|
|
@@ -14215,6 +14761,7 @@ async function buildApp(options = {}) {
|
|
|
14215
14761
|
});
|
|
14216
14762
|
writeClientBoostrapManifest(projectRoot);
|
|
14217
14763
|
writeClientRoutesManifest(routes, projectRoot);
|
|
14764
|
+
await writeRewritesManifest(projectRoot);
|
|
14218
14765
|
await buildClientBundle(projectRoot);
|
|
14219
14766
|
await buildStaticPages(projectRoot, routes, config);
|
|
14220
14767
|
delete process.env.LOLY_BUILD;
|
|
@@ -14222,16 +14769,16 @@ async function buildApp(options = {}) {
|
|
|
14222
14769
|
}
|
|
14223
14770
|
|
|
14224
14771
|
// src/server.ts
|
|
14225
|
-
var
|
|
14226
|
-
var
|
|
14772
|
+
var import_fs23 = __toESM(require("fs"));
|
|
14773
|
+
var import_path33 = __toESM(require("path"));
|
|
14227
14774
|
|
|
14228
14775
|
// modules/server/setup.ts
|
|
14229
14776
|
var import_express = __toESM(require("express"));
|
|
14230
|
-
var
|
|
14231
|
-
var
|
|
14777
|
+
var import_path31 = __toESM(require("path"));
|
|
14778
|
+
var import_fs22 = __toESM(require("fs"));
|
|
14232
14779
|
|
|
14233
14780
|
// ../../node_modules/.pnpm/chokidar@4.0.3/node_modules/chokidar/esm/index.js
|
|
14234
|
-
var
|
|
14781
|
+
var import_fs21 = require("fs");
|
|
14235
14782
|
var import_promises3 = require("fs/promises");
|
|
14236
14783
|
var import_events = require("events");
|
|
14237
14784
|
var sysPath2 = __toESM(require("path"), 1);
|
|
@@ -14306,7 +14853,7 @@ var ReaddirpStream = class extends import_node_stream.Readable {
|
|
|
14306
14853
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
14307
14854
|
const statMethod = opts.lstat ? import_promises.lstat : import_promises.stat;
|
|
14308
14855
|
if (wantBigintFsStats) {
|
|
14309
|
-
this._stat = (
|
|
14856
|
+
this._stat = (path31) => statMethod(path31, { bigint: true });
|
|
14310
14857
|
} else {
|
|
14311
14858
|
this._stat = statMethod;
|
|
14312
14859
|
}
|
|
@@ -14331,8 +14878,8 @@ var ReaddirpStream = class extends import_node_stream.Readable {
|
|
|
14331
14878
|
const par = this.parent;
|
|
14332
14879
|
const fil = par && par.files;
|
|
14333
14880
|
if (fil && fil.length > 0) {
|
|
14334
|
-
const { path:
|
|
14335
|
-
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent,
|
|
14881
|
+
const { path: path31, depth } = par;
|
|
14882
|
+
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path31));
|
|
14336
14883
|
const awaited = await Promise.all(slice);
|
|
14337
14884
|
for (const entry of awaited) {
|
|
14338
14885
|
if (!entry)
|
|
@@ -14372,20 +14919,20 @@ var ReaddirpStream = class extends import_node_stream.Readable {
|
|
|
14372
14919
|
this.reading = false;
|
|
14373
14920
|
}
|
|
14374
14921
|
}
|
|
14375
|
-
async _exploreDir(
|
|
14922
|
+
async _exploreDir(path31, depth) {
|
|
14376
14923
|
let files;
|
|
14377
14924
|
try {
|
|
14378
|
-
files = await (0, import_promises.readdir)(
|
|
14925
|
+
files = await (0, import_promises.readdir)(path31, this._rdOptions);
|
|
14379
14926
|
} catch (error) {
|
|
14380
14927
|
this._onError(error);
|
|
14381
14928
|
}
|
|
14382
|
-
return { files, depth, path:
|
|
14929
|
+
return { files, depth, path: path31 };
|
|
14383
14930
|
}
|
|
14384
|
-
async _formatEntry(dirent,
|
|
14931
|
+
async _formatEntry(dirent, path31) {
|
|
14385
14932
|
let entry;
|
|
14386
14933
|
const basename3 = this._isDirent ? dirent.name : dirent;
|
|
14387
14934
|
try {
|
|
14388
|
-
const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(
|
|
14935
|
+
const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path31, basename3));
|
|
14389
14936
|
entry = { path: (0, import_node_path.relative)(this._root, fullPath), fullPath, basename: basename3 };
|
|
14390
14937
|
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
14391
14938
|
} catch (err) {
|
|
@@ -14456,7 +15003,7 @@ function readdirp(root, options = {}) {
|
|
|
14456
15003
|
}
|
|
14457
15004
|
|
|
14458
15005
|
// ../../node_modules/.pnpm/chokidar@4.0.3/node_modules/chokidar/esm/handler.js
|
|
14459
|
-
var
|
|
15006
|
+
var import_fs20 = require("fs");
|
|
14460
15007
|
var import_promises2 = require("fs/promises");
|
|
14461
15008
|
var sysPath = __toESM(require("path"), 1);
|
|
14462
15009
|
var import_os = require("os");
|
|
@@ -14785,16 +15332,16 @@ var delFromSet = (main, prop, item) => {
|
|
|
14785
15332
|
};
|
|
14786
15333
|
var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
|
|
14787
15334
|
var FsWatchInstances = /* @__PURE__ */ new Map();
|
|
14788
|
-
function createFsWatchInstance(
|
|
15335
|
+
function createFsWatchInstance(path31, options, listener, errHandler, emitRaw) {
|
|
14789
15336
|
const handleEvent = (rawEvent, evPath) => {
|
|
14790
|
-
listener(
|
|
14791
|
-
emitRaw(rawEvent, evPath, { watchedPath:
|
|
14792
|
-
if (evPath &&
|
|
14793
|
-
fsWatchBroadcast(sysPath.resolve(
|
|
15337
|
+
listener(path31);
|
|
15338
|
+
emitRaw(rawEvent, evPath, { watchedPath: path31 });
|
|
15339
|
+
if (evPath && path31 !== evPath) {
|
|
15340
|
+
fsWatchBroadcast(sysPath.resolve(path31, evPath), KEY_LISTENERS, sysPath.join(path31, evPath));
|
|
14794
15341
|
}
|
|
14795
15342
|
};
|
|
14796
15343
|
try {
|
|
14797
|
-
return (0,
|
|
15344
|
+
return (0, import_fs20.watch)(path31, {
|
|
14798
15345
|
persistent: options.persistent
|
|
14799
15346
|
}, handleEvent);
|
|
14800
15347
|
} catch (error) {
|
|
@@ -14810,12 +15357,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
|
|
|
14810
15357
|
listener(val1, val2, val3);
|
|
14811
15358
|
});
|
|
14812
15359
|
};
|
|
14813
|
-
var setFsWatchListener = (
|
|
15360
|
+
var setFsWatchListener = (path31, fullPath, options, handlers) => {
|
|
14814
15361
|
const { listener, errHandler, rawEmitter } = handlers;
|
|
14815
15362
|
let cont = FsWatchInstances.get(fullPath);
|
|
14816
15363
|
let watcher;
|
|
14817
15364
|
if (!options.persistent) {
|
|
14818
|
-
watcher = createFsWatchInstance(
|
|
15365
|
+
watcher = createFsWatchInstance(path31, options, listener, errHandler, rawEmitter);
|
|
14819
15366
|
if (!watcher)
|
|
14820
15367
|
return;
|
|
14821
15368
|
return watcher.close.bind(watcher);
|
|
@@ -14826,7 +15373,7 @@ var setFsWatchListener = (path29, fullPath, options, handlers) => {
|
|
|
14826
15373
|
addAndConvert(cont, KEY_RAW, rawEmitter);
|
|
14827
15374
|
} else {
|
|
14828
15375
|
watcher = createFsWatchInstance(
|
|
14829
|
-
|
|
15376
|
+
path31,
|
|
14830
15377
|
options,
|
|
14831
15378
|
fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
|
|
14832
15379
|
errHandler,
|
|
@@ -14841,7 +15388,7 @@ var setFsWatchListener = (path29, fullPath, options, handlers) => {
|
|
|
14841
15388
|
cont.watcherUnusable = true;
|
|
14842
15389
|
if (isWindows && error.code === "EPERM") {
|
|
14843
15390
|
try {
|
|
14844
|
-
const fd = await (0, import_promises2.open)(
|
|
15391
|
+
const fd = await (0, import_promises2.open)(path31, "r");
|
|
14845
15392
|
await fd.close();
|
|
14846
15393
|
broadcastErr(error);
|
|
14847
15394
|
} catch (err) {
|
|
@@ -14872,12 +15419,12 @@ var setFsWatchListener = (path29, fullPath, options, handlers) => {
|
|
|
14872
15419
|
};
|
|
14873
15420
|
};
|
|
14874
15421
|
var FsWatchFileInstances = /* @__PURE__ */ new Map();
|
|
14875
|
-
var setFsWatchFileListener = (
|
|
15422
|
+
var setFsWatchFileListener = (path31, fullPath, options, handlers) => {
|
|
14876
15423
|
const { listener, rawEmitter } = handlers;
|
|
14877
15424
|
let cont = FsWatchFileInstances.get(fullPath);
|
|
14878
15425
|
const copts = cont && cont.options;
|
|
14879
15426
|
if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) {
|
|
14880
|
-
(0,
|
|
15427
|
+
(0, import_fs20.unwatchFile)(fullPath);
|
|
14881
15428
|
cont = void 0;
|
|
14882
15429
|
}
|
|
14883
15430
|
if (cont) {
|
|
@@ -14888,13 +15435,13 @@ var setFsWatchFileListener = (path29, fullPath, options, handlers) => {
|
|
|
14888
15435
|
listeners: listener,
|
|
14889
15436
|
rawEmitters: rawEmitter,
|
|
14890
15437
|
options,
|
|
14891
|
-
watcher: (0,
|
|
15438
|
+
watcher: (0, import_fs20.watchFile)(fullPath, options, (curr, prev) => {
|
|
14892
15439
|
foreach(cont.rawEmitters, (rawEmitter2) => {
|
|
14893
15440
|
rawEmitter2(EV.CHANGE, fullPath, { curr, prev });
|
|
14894
15441
|
});
|
|
14895
15442
|
const currmtime = curr.mtimeMs;
|
|
14896
15443
|
if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
|
|
14897
|
-
foreach(cont.listeners, (listener2) => listener2(
|
|
15444
|
+
foreach(cont.listeners, (listener2) => listener2(path31, curr));
|
|
14898
15445
|
}
|
|
14899
15446
|
})
|
|
14900
15447
|
};
|
|
@@ -14905,7 +15452,7 @@ var setFsWatchFileListener = (path29, fullPath, options, handlers) => {
|
|
|
14905
15452
|
delFromSet(cont, KEY_RAW, rawEmitter);
|
|
14906
15453
|
if (isEmptySet(cont.listeners)) {
|
|
14907
15454
|
FsWatchFileInstances.delete(fullPath);
|
|
14908
|
-
(0,
|
|
15455
|
+
(0, import_fs20.unwatchFile)(fullPath);
|
|
14909
15456
|
cont.options = cont.watcher = void 0;
|
|
14910
15457
|
Object.freeze(cont);
|
|
14911
15458
|
}
|
|
@@ -14922,13 +15469,13 @@ var NodeFsHandler = class {
|
|
|
14922
15469
|
* @param listener on fs change
|
|
14923
15470
|
* @returns closer for the watcher instance
|
|
14924
15471
|
*/
|
|
14925
|
-
_watchWithNodeFs(
|
|
15472
|
+
_watchWithNodeFs(path31, listener) {
|
|
14926
15473
|
const opts = this.fsw.options;
|
|
14927
|
-
const directory = sysPath.dirname(
|
|
14928
|
-
const basename3 = sysPath.basename(
|
|
15474
|
+
const directory = sysPath.dirname(path31);
|
|
15475
|
+
const basename3 = sysPath.basename(path31);
|
|
14929
15476
|
const parent = this.fsw._getWatchedDir(directory);
|
|
14930
15477
|
parent.add(basename3);
|
|
14931
|
-
const absolutePath = sysPath.resolve(
|
|
15478
|
+
const absolutePath = sysPath.resolve(path31);
|
|
14932
15479
|
const options = {
|
|
14933
15480
|
persistent: opts.persistent
|
|
14934
15481
|
};
|
|
@@ -14938,12 +15485,12 @@ var NodeFsHandler = class {
|
|
|
14938
15485
|
if (opts.usePolling) {
|
|
14939
15486
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
14940
15487
|
options.interval = enableBin && isBinaryPath(basename3) ? opts.binaryInterval : opts.interval;
|
|
14941
|
-
closer = setFsWatchFileListener(
|
|
15488
|
+
closer = setFsWatchFileListener(path31, absolutePath, options, {
|
|
14942
15489
|
listener,
|
|
14943
15490
|
rawEmitter: this.fsw._emitRaw
|
|
14944
15491
|
});
|
|
14945
15492
|
} else {
|
|
14946
|
-
closer = setFsWatchListener(
|
|
15493
|
+
closer = setFsWatchListener(path31, absolutePath, options, {
|
|
14947
15494
|
listener,
|
|
14948
15495
|
errHandler: this._boundHandleError,
|
|
14949
15496
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -14965,7 +15512,7 @@ var NodeFsHandler = class {
|
|
|
14965
15512
|
let prevStats = stats;
|
|
14966
15513
|
if (parent.has(basename3))
|
|
14967
15514
|
return;
|
|
14968
|
-
const listener = async (
|
|
15515
|
+
const listener = async (path31, newStats) => {
|
|
14969
15516
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
|
|
14970
15517
|
return;
|
|
14971
15518
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
@@ -14979,11 +15526,11 @@ var NodeFsHandler = class {
|
|
|
14979
15526
|
this.fsw._emit(EV.CHANGE, file, newStats2);
|
|
14980
15527
|
}
|
|
14981
15528
|
if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
|
|
14982
|
-
this.fsw._closeFile(
|
|
15529
|
+
this.fsw._closeFile(path31);
|
|
14983
15530
|
prevStats = newStats2;
|
|
14984
15531
|
const closer2 = this._watchWithNodeFs(file, listener);
|
|
14985
15532
|
if (closer2)
|
|
14986
|
-
this.fsw._addPathCloser(
|
|
15533
|
+
this.fsw._addPathCloser(path31, closer2);
|
|
14987
15534
|
} else {
|
|
14988
15535
|
prevStats = newStats2;
|
|
14989
15536
|
}
|
|
@@ -15015,7 +15562,7 @@ var NodeFsHandler = class {
|
|
|
15015
15562
|
* @param item basename of this item
|
|
15016
15563
|
* @returns true if no more processing is needed for this entry.
|
|
15017
15564
|
*/
|
|
15018
|
-
async _handleSymlink(entry, directory,
|
|
15565
|
+
async _handleSymlink(entry, directory, path31, item) {
|
|
15019
15566
|
if (this.fsw.closed) {
|
|
15020
15567
|
return;
|
|
15021
15568
|
}
|
|
@@ -15025,7 +15572,7 @@ var NodeFsHandler = class {
|
|
|
15025
15572
|
this.fsw._incrReadyCount();
|
|
15026
15573
|
let linkPath;
|
|
15027
15574
|
try {
|
|
15028
|
-
linkPath = await (0, import_promises2.realpath)(
|
|
15575
|
+
linkPath = await (0, import_promises2.realpath)(path31);
|
|
15029
15576
|
} catch (e) {
|
|
15030
15577
|
this.fsw._emitReady();
|
|
15031
15578
|
return true;
|
|
@@ -15035,12 +15582,12 @@ var NodeFsHandler = class {
|
|
|
15035
15582
|
if (dir.has(item)) {
|
|
15036
15583
|
if (this.fsw._symlinkPaths.get(full) !== linkPath) {
|
|
15037
15584
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
15038
|
-
this.fsw._emit(EV.CHANGE,
|
|
15585
|
+
this.fsw._emit(EV.CHANGE, path31, entry.stats);
|
|
15039
15586
|
}
|
|
15040
15587
|
} else {
|
|
15041
15588
|
dir.add(item);
|
|
15042
15589
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
15043
|
-
this.fsw._emit(EV.ADD,
|
|
15590
|
+
this.fsw._emit(EV.ADD, path31, entry.stats);
|
|
15044
15591
|
}
|
|
15045
15592
|
this.fsw._emitReady();
|
|
15046
15593
|
return true;
|
|
@@ -15069,9 +15616,9 @@ var NodeFsHandler = class {
|
|
|
15069
15616
|
return;
|
|
15070
15617
|
}
|
|
15071
15618
|
const item = entry.path;
|
|
15072
|
-
let
|
|
15619
|
+
let path31 = sysPath.join(directory, item);
|
|
15073
15620
|
current.add(item);
|
|
15074
|
-
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory,
|
|
15621
|
+
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path31, item)) {
|
|
15075
15622
|
return;
|
|
15076
15623
|
}
|
|
15077
15624
|
if (this.fsw.closed) {
|
|
@@ -15080,8 +15627,8 @@ var NodeFsHandler = class {
|
|
|
15080
15627
|
}
|
|
15081
15628
|
if (item === target || !target && !previous.has(item)) {
|
|
15082
15629
|
this.fsw._incrReadyCount();
|
|
15083
|
-
|
|
15084
|
-
this._addToNodeFs(
|
|
15630
|
+
path31 = sysPath.join(dir, sysPath.relative(dir, path31));
|
|
15631
|
+
this._addToNodeFs(path31, initialAdd, wh, depth + 1);
|
|
15085
15632
|
}
|
|
15086
15633
|
}).on(EV.ERROR, this._boundHandleError);
|
|
15087
15634
|
return new Promise((resolve3, reject) => {
|
|
@@ -15150,13 +15697,13 @@ var NodeFsHandler = class {
|
|
|
15150
15697
|
* @param depth Child path actually targeted for watch
|
|
15151
15698
|
* @param target Child path actually targeted for watch
|
|
15152
15699
|
*/
|
|
15153
|
-
async _addToNodeFs(
|
|
15700
|
+
async _addToNodeFs(path31, initialAdd, priorWh, depth, target) {
|
|
15154
15701
|
const ready = this.fsw._emitReady;
|
|
15155
|
-
if (this.fsw._isIgnored(
|
|
15702
|
+
if (this.fsw._isIgnored(path31) || this.fsw.closed) {
|
|
15156
15703
|
ready();
|
|
15157
15704
|
return false;
|
|
15158
15705
|
}
|
|
15159
|
-
const wh = this.fsw._getWatchHelpers(
|
|
15706
|
+
const wh = this.fsw._getWatchHelpers(path31);
|
|
15160
15707
|
if (priorWh) {
|
|
15161
15708
|
wh.filterPath = (entry) => priorWh.filterPath(entry);
|
|
15162
15709
|
wh.filterDir = (entry) => priorWh.filterDir(entry);
|
|
@@ -15172,8 +15719,8 @@ var NodeFsHandler = class {
|
|
|
15172
15719
|
const follow = this.fsw.options.followSymlinks;
|
|
15173
15720
|
let closer;
|
|
15174
15721
|
if (stats.isDirectory()) {
|
|
15175
|
-
const absPath = sysPath.resolve(
|
|
15176
|
-
const targetPath = follow ? await (0, import_promises2.realpath)(
|
|
15722
|
+
const absPath = sysPath.resolve(path31);
|
|
15723
|
+
const targetPath = follow ? await (0, import_promises2.realpath)(path31) : path31;
|
|
15177
15724
|
if (this.fsw.closed)
|
|
15178
15725
|
return;
|
|
15179
15726
|
closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
|
|
@@ -15183,29 +15730,29 @@ var NodeFsHandler = class {
|
|
|
15183
15730
|
this.fsw._symlinkPaths.set(absPath, targetPath);
|
|
15184
15731
|
}
|
|
15185
15732
|
} else if (stats.isSymbolicLink()) {
|
|
15186
|
-
const targetPath = follow ? await (0, import_promises2.realpath)(
|
|
15733
|
+
const targetPath = follow ? await (0, import_promises2.realpath)(path31) : path31;
|
|
15187
15734
|
if (this.fsw.closed)
|
|
15188
15735
|
return;
|
|
15189
15736
|
const parent = sysPath.dirname(wh.watchPath);
|
|
15190
15737
|
this.fsw._getWatchedDir(parent).add(wh.watchPath);
|
|
15191
15738
|
this.fsw._emit(EV.ADD, wh.watchPath, stats);
|
|
15192
|
-
closer = await this._handleDir(parent, stats, initialAdd, depth,
|
|
15739
|
+
closer = await this._handleDir(parent, stats, initialAdd, depth, path31, wh, targetPath);
|
|
15193
15740
|
if (this.fsw.closed)
|
|
15194
15741
|
return;
|
|
15195
15742
|
if (targetPath !== void 0) {
|
|
15196
|
-
this.fsw._symlinkPaths.set(sysPath.resolve(
|
|
15743
|
+
this.fsw._symlinkPaths.set(sysPath.resolve(path31), targetPath);
|
|
15197
15744
|
}
|
|
15198
15745
|
} else {
|
|
15199
15746
|
closer = this._handleFile(wh.watchPath, stats, initialAdd);
|
|
15200
15747
|
}
|
|
15201
15748
|
ready();
|
|
15202
15749
|
if (closer)
|
|
15203
|
-
this.fsw._addPathCloser(
|
|
15750
|
+
this.fsw._addPathCloser(path31, closer);
|
|
15204
15751
|
return false;
|
|
15205
15752
|
} catch (error) {
|
|
15206
15753
|
if (this.fsw._handleError(error)) {
|
|
15207
15754
|
ready();
|
|
15208
|
-
return
|
|
15755
|
+
return path31;
|
|
15209
15756
|
}
|
|
15210
15757
|
}
|
|
15211
15758
|
}
|
|
@@ -15248,26 +15795,26 @@ function createPattern(matcher) {
|
|
|
15248
15795
|
}
|
|
15249
15796
|
return () => false;
|
|
15250
15797
|
}
|
|
15251
|
-
function normalizePath(
|
|
15252
|
-
if (typeof
|
|
15798
|
+
function normalizePath(path31) {
|
|
15799
|
+
if (typeof path31 !== "string")
|
|
15253
15800
|
throw new Error("string expected");
|
|
15254
|
-
|
|
15255
|
-
|
|
15801
|
+
path31 = sysPath2.normalize(path31);
|
|
15802
|
+
path31 = path31.replace(/\\/g, "/");
|
|
15256
15803
|
let prepend = false;
|
|
15257
|
-
if (
|
|
15804
|
+
if (path31.startsWith("//"))
|
|
15258
15805
|
prepend = true;
|
|
15259
15806
|
const DOUBLE_SLASH_RE2 = /\/\//;
|
|
15260
|
-
while (
|
|
15261
|
-
|
|
15807
|
+
while (path31.match(DOUBLE_SLASH_RE2))
|
|
15808
|
+
path31 = path31.replace(DOUBLE_SLASH_RE2, "/");
|
|
15262
15809
|
if (prepend)
|
|
15263
|
-
|
|
15264
|
-
return
|
|
15810
|
+
path31 = "/" + path31;
|
|
15811
|
+
return path31;
|
|
15265
15812
|
}
|
|
15266
15813
|
function matchPatterns(patterns, testString, stats) {
|
|
15267
|
-
const
|
|
15814
|
+
const path31 = normalizePath(testString);
|
|
15268
15815
|
for (let index = 0; index < patterns.length; index++) {
|
|
15269
15816
|
const pattern = patterns[index];
|
|
15270
|
-
if (pattern(
|
|
15817
|
+
if (pattern(path31, stats)) {
|
|
15271
15818
|
return true;
|
|
15272
15819
|
}
|
|
15273
15820
|
}
|
|
@@ -15307,19 +15854,19 @@ var toUnix = (string) => {
|
|
|
15307
15854
|
}
|
|
15308
15855
|
return str;
|
|
15309
15856
|
};
|
|
15310
|
-
var normalizePathToUnix = (
|
|
15311
|
-
var normalizeIgnored = (cwd = "") => (
|
|
15312
|
-
if (typeof
|
|
15313
|
-
return normalizePathToUnix(sysPath2.isAbsolute(
|
|
15857
|
+
var normalizePathToUnix = (path31) => toUnix(sysPath2.normalize(toUnix(path31)));
|
|
15858
|
+
var normalizeIgnored = (cwd = "") => (path31) => {
|
|
15859
|
+
if (typeof path31 === "string") {
|
|
15860
|
+
return normalizePathToUnix(sysPath2.isAbsolute(path31) ? path31 : sysPath2.join(cwd, path31));
|
|
15314
15861
|
} else {
|
|
15315
|
-
return
|
|
15862
|
+
return path31;
|
|
15316
15863
|
}
|
|
15317
15864
|
};
|
|
15318
|
-
var getAbsolutePath = (
|
|
15319
|
-
if (sysPath2.isAbsolute(
|
|
15320
|
-
return
|
|
15865
|
+
var getAbsolutePath = (path31, cwd) => {
|
|
15866
|
+
if (sysPath2.isAbsolute(path31)) {
|
|
15867
|
+
return path31;
|
|
15321
15868
|
}
|
|
15322
|
-
return sysPath2.join(cwd,
|
|
15869
|
+
return sysPath2.join(cwd, path31);
|
|
15323
15870
|
};
|
|
15324
15871
|
var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
|
|
15325
15872
|
var DirEntry = class {
|
|
@@ -15374,10 +15921,10 @@ var DirEntry = class {
|
|
|
15374
15921
|
var STAT_METHOD_F = "stat";
|
|
15375
15922
|
var STAT_METHOD_L = "lstat";
|
|
15376
15923
|
var WatchHelper = class {
|
|
15377
|
-
constructor(
|
|
15924
|
+
constructor(path31, follow, fsw) {
|
|
15378
15925
|
this.fsw = fsw;
|
|
15379
|
-
const watchPath =
|
|
15380
|
-
this.path =
|
|
15926
|
+
const watchPath = path31;
|
|
15927
|
+
this.path = path31 = path31.replace(REPLACER_RE, "");
|
|
15381
15928
|
this.watchPath = watchPath;
|
|
15382
15929
|
this.fullWatchPath = sysPath2.resolve(watchPath);
|
|
15383
15930
|
this.dirParts = [];
|
|
@@ -15499,20 +16046,20 @@ var FSWatcher = class extends import_events.EventEmitter {
|
|
|
15499
16046
|
this._closePromise = void 0;
|
|
15500
16047
|
let paths = unifyPaths(paths_);
|
|
15501
16048
|
if (cwd) {
|
|
15502
|
-
paths = paths.map((
|
|
15503
|
-
const absPath = getAbsolutePath(
|
|
16049
|
+
paths = paths.map((path31) => {
|
|
16050
|
+
const absPath = getAbsolutePath(path31, cwd);
|
|
15504
16051
|
return absPath;
|
|
15505
16052
|
});
|
|
15506
16053
|
}
|
|
15507
|
-
paths.forEach((
|
|
15508
|
-
this._removeIgnoredPath(
|
|
16054
|
+
paths.forEach((path31) => {
|
|
16055
|
+
this._removeIgnoredPath(path31);
|
|
15509
16056
|
});
|
|
15510
16057
|
this._userIgnored = void 0;
|
|
15511
16058
|
if (!this._readyCount)
|
|
15512
16059
|
this._readyCount = 0;
|
|
15513
16060
|
this._readyCount += paths.length;
|
|
15514
|
-
Promise.all(paths.map(async (
|
|
15515
|
-
const res = await this._nodeFsHandler._addToNodeFs(
|
|
16061
|
+
Promise.all(paths.map(async (path31) => {
|
|
16062
|
+
const res = await this._nodeFsHandler._addToNodeFs(path31, !_internal, void 0, 0, _origAdd);
|
|
15516
16063
|
if (res)
|
|
15517
16064
|
this._emitReady();
|
|
15518
16065
|
return res;
|
|
@@ -15534,17 +16081,17 @@ var FSWatcher = class extends import_events.EventEmitter {
|
|
|
15534
16081
|
return this;
|
|
15535
16082
|
const paths = unifyPaths(paths_);
|
|
15536
16083
|
const { cwd } = this.options;
|
|
15537
|
-
paths.forEach((
|
|
15538
|
-
if (!sysPath2.isAbsolute(
|
|
16084
|
+
paths.forEach((path31) => {
|
|
16085
|
+
if (!sysPath2.isAbsolute(path31) && !this._closers.has(path31)) {
|
|
15539
16086
|
if (cwd)
|
|
15540
|
-
|
|
15541
|
-
|
|
16087
|
+
path31 = sysPath2.join(cwd, path31);
|
|
16088
|
+
path31 = sysPath2.resolve(path31);
|
|
15542
16089
|
}
|
|
15543
|
-
this._closePath(
|
|
15544
|
-
this._addIgnoredPath(
|
|
15545
|
-
if (this._watched.has(
|
|
16090
|
+
this._closePath(path31);
|
|
16091
|
+
this._addIgnoredPath(path31);
|
|
16092
|
+
if (this._watched.has(path31)) {
|
|
15546
16093
|
this._addIgnoredPath({
|
|
15547
|
-
path:
|
|
16094
|
+
path: path31,
|
|
15548
16095
|
recursive: true
|
|
15549
16096
|
});
|
|
15550
16097
|
}
|
|
@@ -15608,38 +16155,38 @@ var FSWatcher = class extends import_events.EventEmitter {
|
|
|
15608
16155
|
* @param stats arguments to be passed with event
|
|
15609
16156
|
* @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
|
|
15610
16157
|
*/
|
|
15611
|
-
async _emit(event,
|
|
16158
|
+
async _emit(event, path31, stats) {
|
|
15612
16159
|
if (this.closed)
|
|
15613
16160
|
return;
|
|
15614
16161
|
const opts = this.options;
|
|
15615
16162
|
if (isWindows)
|
|
15616
|
-
|
|
16163
|
+
path31 = sysPath2.normalize(path31);
|
|
15617
16164
|
if (opts.cwd)
|
|
15618
|
-
|
|
15619
|
-
const args = [
|
|
16165
|
+
path31 = sysPath2.relative(opts.cwd, path31);
|
|
16166
|
+
const args = [path31];
|
|
15620
16167
|
if (stats != null)
|
|
15621
16168
|
args.push(stats);
|
|
15622
16169
|
const awf = opts.awaitWriteFinish;
|
|
15623
16170
|
let pw;
|
|
15624
|
-
if (awf && (pw = this._pendingWrites.get(
|
|
16171
|
+
if (awf && (pw = this._pendingWrites.get(path31))) {
|
|
15625
16172
|
pw.lastChange = /* @__PURE__ */ new Date();
|
|
15626
16173
|
return this;
|
|
15627
16174
|
}
|
|
15628
16175
|
if (opts.atomic) {
|
|
15629
16176
|
if (event === EVENTS.UNLINK) {
|
|
15630
|
-
this._pendingUnlinks.set(
|
|
16177
|
+
this._pendingUnlinks.set(path31, [event, ...args]);
|
|
15631
16178
|
setTimeout(() => {
|
|
15632
|
-
this._pendingUnlinks.forEach((entry,
|
|
16179
|
+
this._pendingUnlinks.forEach((entry, path32) => {
|
|
15633
16180
|
this.emit(...entry);
|
|
15634
16181
|
this.emit(EVENTS.ALL, ...entry);
|
|
15635
|
-
this._pendingUnlinks.delete(
|
|
16182
|
+
this._pendingUnlinks.delete(path32);
|
|
15636
16183
|
});
|
|
15637
16184
|
}, typeof opts.atomic === "number" ? opts.atomic : 100);
|
|
15638
16185
|
return this;
|
|
15639
16186
|
}
|
|
15640
|
-
if (event === EVENTS.ADD && this._pendingUnlinks.has(
|
|
16187
|
+
if (event === EVENTS.ADD && this._pendingUnlinks.has(path31)) {
|
|
15641
16188
|
event = EVENTS.CHANGE;
|
|
15642
|
-
this._pendingUnlinks.delete(
|
|
16189
|
+
this._pendingUnlinks.delete(path31);
|
|
15643
16190
|
}
|
|
15644
16191
|
}
|
|
15645
16192
|
if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
|
|
@@ -15657,16 +16204,16 @@ var FSWatcher = class extends import_events.EventEmitter {
|
|
|
15657
16204
|
this.emitWithAll(event, args);
|
|
15658
16205
|
}
|
|
15659
16206
|
};
|
|
15660
|
-
this._awaitWriteFinish(
|
|
16207
|
+
this._awaitWriteFinish(path31, awf.stabilityThreshold, event, awfEmit);
|
|
15661
16208
|
return this;
|
|
15662
16209
|
}
|
|
15663
16210
|
if (event === EVENTS.CHANGE) {
|
|
15664
|
-
const isThrottled = !this._throttle(EVENTS.CHANGE,
|
|
16211
|
+
const isThrottled = !this._throttle(EVENTS.CHANGE, path31, 50);
|
|
15665
16212
|
if (isThrottled)
|
|
15666
16213
|
return this;
|
|
15667
16214
|
}
|
|
15668
16215
|
if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
|
|
15669
|
-
const fullPath = opts.cwd ? sysPath2.join(opts.cwd,
|
|
16216
|
+
const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path31) : path31;
|
|
15670
16217
|
let stats2;
|
|
15671
16218
|
try {
|
|
15672
16219
|
stats2 = await (0, import_promises3.stat)(fullPath);
|
|
@@ -15697,23 +16244,23 @@ var FSWatcher = class extends import_events.EventEmitter {
|
|
|
15697
16244
|
* @param timeout duration of time to suppress duplicate actions
|
|
15698
16245
|
* @returns tracking object or false if action should be suppressed
|
|
15699
16246
|
*/
|
|
15700
|
-
_throttle(actionType,
|
|
16247
|
+
_throttle(actionType, path31, timeout) {
|
|
15701
16248
|
if (!this._throttled.has(actionType)) {
|
|
15702
16249
|
this._throttled.set(actionType, /* @__PURE__ */ new Map());
|
|
15703
16250
|
}
|
|
15704
16251
|
const action = this._throttled.get(actionType);
|
|
15705
16252
|
if (!action)
|
|
15706
16253
|
throw new Error("invalid throttle");
|
|
15707
|
-
const actionPath = action.get(
|
|
16254
|
+
const actionPath = action.get(path31);
|
|
15708
16255
|
if (actionPath) {
|
|
15709
16256
|
actionPath.count++;
|
|
15710
16257
|
return false;
|
|
15711
16258
|
}
|
|
15712
16259
|
let timeoutObject;
|
|
15713
16260
|
const clear = () => {
|
|
15714
|
-
const item = action.get(
|
|
16261
|
+
const item = action.get(path31);
|
|
15715
16262
|
const count = item ? item.count : 0;
|
|
15716
|
-
action.delete(
|
|
16263
|
+
action.delete(path31);
|
|
15717
16264
|
clearTimeout(timeoutObject);
|
|
15718
16265
|
if (item)
|
|
15719
16266
|
clearTimeout(item.timeoutObject);
|
|
@@ -15721,7 +16268,7 @@ var FSWatcher = class extends import_events.EventEmitter {
|
|
|
15721
16268
|
};
|
|
15722
16269
|
timeoutObject = setTimeout(clear, timeout);
|
|
15723
16270
|
const thr = { timeoutObject, clear, count: 0 };
|
|
15724
|
-
action.set(
|
|
16271
|
+
action.set(path31, thr);
|
|
15725
16272
|
return thr;
|
|
15726
16273
|
}
|
|
15727
16274
|
_incrReadyCount() {
|
|
@@ -15735,44 +16282,44 @@ var FSWatcher = class extends import_events.EventEmitter {
|
|
|
15735
16282
|
* @param event
|
|
15736
16283
|
* @param awfEmit Callback to be called when ready for event to be emitted.
|
|
15737
16284
|
*/
|
|
15738
|
-
_awaitWriteFinish(
|
|
16285
|
+
_awaitWriteFinish(path31, threshold, event, awfEmit) {
|
|
15739
16286
|
const awf = this.options.awaitWriteFinish;
|
|
15740
16287
|
if (typeof awf !== "object")
|
|
15741
16288
|
return;
|
|
15742
16289
|
const pollInterval = awf.pollInterval;
|
|
15743
16290
|
let timeoutHandler;
|
|
15744
|
-
let fullPath =
|
|
15745
|
-
if (this.options.cwd && !sysPath2.isAbsolute(
|
|
15746
|
-
fullPath = sysPath2.join(this.options.cwd,
|
|
16291
|
+
let fullPath = path31;
|
|
16292
|
+
if (this.options.cwd && !sysPath2.isAbsolute(path31)) {
|
|
16293
|
+
fullPath = sysPath2.join(this.options.cwd, path31);
|
|
15747
16294
|
}
|
|
15748
16295
|
const now = /* @__PURE__ */ new Date();
|
|
15749
16296
|
const writes = this._pendingWrites;
|
|
15750
16297
|
function awaitWriteFinishFn(prevStat) {
|
|
15751
|
-
(0,
|
|
15752
|
-
if (err || !writes.has(
|
|
16298
|
+
(0, import_fs21.stat)(fullPath, (err, curStat) => {
|
|
16299
|
+
if (err || !writes.has(path31)) {
|
|
15753
16300
|
if (err && err.code !== "ENOENT")
|
|
15754
16301
|
awfEmit(err);
|
|
15755
16302
|
return;
|
|
15756
16303
|
}
|
|
15757
16304
|
const now2 = Number(/* @__PURE__ */ new Date());
|
|
15758
16305
|
if (prevStat && curStat.size !== prevStat.size) {
|
|
15759
|
-
writes.get(
|
|
16306
|
+
writes.get(path31).lastChange = now2;
|
|
15760
16307
|
}
|
|
15761
|
-
const pw = writes.get(
|
|
16308
|
+
const pw = writes.get(path31);
|
|
15762
16309
|
const df = now2 - pw.lastChange;
|
|
15763
16310
|
if (df >= threshold) {
|
|
15764
|
-
writes.delete(
|
|
16311
|
+
writes.delete(path31);
|
|
15765
16312
|
awfEmit(void 0, curStat);
|
|
15766
16313
|
} else {
|
|
15767
16314
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
|
|
15768
16315
|
}
|
|
15769
16316
|
});
|
|
15770
16317
|
}
|
|
15771
|
-
if (!writes.has(
|
|
15772
|
-
writes.set(
|
|
16318
|
+
if (!writes.has(path31)) {
|
|
16319
|
+
writes.set(path31, {
|
|
15773
16320
|
lastChange: now,
|
|
15774
16321
|
cancelWait: () => {
|
|
15775
|
-
writes.delete(
|
|
16322
|
+
writes.delete(path31);
|
|
15776
16323
|
clearTimeout(timeoutHandler);
|
|
15777
16324
|
return event;
|
|
15778
16325
|
}
|
|
@@ -15783,8 +16330,8 @@ var FSWatcher = class extends import_events.EventEmitter {
|
|
|
15783
16330
|
/**
|
|
15784
16331
|
* Determines whether user has asked to ignore this path.
|
|
15785
16332
|
*/
|
|
15786
|
-
_isIgnored(
|
|
15787
|
-
if (this.options.atomic && DOT_RE.test(
|
|
16333
|
+
_isIgnored(path31, stats) {
|
|
16334
|
+
if (this.options.atomic && DOT_RE.test(path31))
|
|
15788
16335
|
return true;
|
|
15789
16336
|
if (!this._userIgnored) {
|
|
15790
16337
|
const { cwd } = this.options;
|
|
@@ -15794,17 +16341,17 @@ var FSWatcher = class extends import_events.EventEmitter {
|
|
|
15794
16341
|
const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
|
|
15795
16342
|
this._userIgnored = anymatch(list, void 0);
|
|
15796
16343
|
}
|
|
15797
|
-
return this._userIgnored(
|
|
16344
|
+
return this._userIgnored(path31, stats);
|
|
15798
16345
|
}
|
|
15799
|
-
_isntIgnored(
|
|
15800
|
-
return !this._isIgnored(
|
|
16346
|
+
_isntIgnored(path31, stat4) {
|
|
16347
|
+
return !this._isIgnored(path31, stat4);
|
|
15801
16348
|
}
|
|
15802
16349
|
/**
|
|
15803
16350
|
* Provides a set of common helpers and properties relating to symlink handling.
|
|
15804
16351
|
* @param path file or directory pattern being watched
|
|
15805
16352
|
*/
|
|
15806
|
-
_getWatchHelpers(
|
|
15807
|
-
return new WatchHelper(
|
|
16353
|
+
_getWatchHelpers(path31) {
|
|
16354
|
+
return new WatchHelper(path31, this.options.followSymlinks, this);
|
|
15808
16355
|
}
|
|
15809
16356
|
// Directory helpers
|
|
15810
16357
|
// -----------------
|
|
@@ -15836,63 +16383,63 @@ var FSWatcher = class extends import_events.EventEmitter {
|
|
|
15836
16383
|
* @param item base path of item/directory
|
|
15837
16384
|
*/
|
|
15838
16385
|
_remove(directory, item, isDirectory) {
|
|
15839
|
-
const
|
|
15840
|
-
const fullPath = sysPath2.resolve(
|
|
15841
|
-
isDirectory = isDirectory != null ? isDirectory : this._watched.has(
|
|
15842
|
-
if (!this._throttle("remove",
|
|
16386
|
+
const path31 = sysPath2.join(directory, item);
|
|
16387
|
+
const fullPath = sysPath2.resolve(path31);
|
|
16388
|
+
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path31) || this._watched.has(fullPath);
|
|
16389
|
+
if (!this._throttle("remove", path31, 100))
|
|
15843
16390
|
return;
|
|
15844
16391
|
if (!isDirectory && this._watched.size === 1) {
|
|
15845
16392
|
this.add(directory, item, true);
|
|
15846
16393
|
}
|
|
15847
|
-
const wp = this._getWatchedDir(
|
|
16394
|
+
const wp = this._getWatchedDir(path31);
|
|
15848
16395
|
const nestedDirectoryChildren = wp.getChildren();
|
|
15849
|
-
nestedDirectoryChildren.forEach((nested) => this._remove(
|
|
16396
|
+
nestedDirectoryChildren.forEach((nested) => this._remove(path31, nested));
|
|
15850
16397
|
const parent = this._getWatchedDir(directory);
|
|
15851
16398
|
const wasTracked = parent.has(item);
|
|
15852
16399
|
parent.remove(item);
|
|
15853
16400
|
if (this._symlinkPaths.has(fullPath)) {
|
|
15854
16401
|
this._symlinkPaths.delete(fullPath);
|
|
15855
16402
|
}
|
|
15856
|
-
let relPath =
|
|
16403
|
+
let relPath = path31;
|
|
15857
16404
|
if (this.options.cwd)
|
|
15858
|
-
relPath = sysPath2.relative(this.options.cwd,
|
|
16405
|
+
relPath = sysPath2.relative(this.options.cwd, path31);
|
|
15859
16406
|
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
15860
16407
|
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
15861
16408
|
if (event === EVENTS.ADD)
|
|
15862
16409
|
return;
|
|
15863
16410
|
}
|
|
15864
|
-
this._watched.delete(
|
|
16411
|
+
this._watched.delete(path31);
|
|
15865
16412
|
this._watched.delete(fullPath);
|
|
15866
16413
|
const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
|
|
15867
|
-
if (wasTracked && !this._isIgnored(
|
|
15868
|
-
this._emit(eventName,
|
|
15869
|
-
this._closePath(
|
|
16414
|
+
if (wasTracked && !this._isIgnored(path31))
|
|
16415
|
+
this._emit(eventName, path31);
|
|
16416
|
+
this._closePath(path31);
|
|
15870
16417
|
}
|
|
15871
16418
|
/**
|
|
15872
16419
|
* Closes all watchers for a path
|
|
15873
16420
|
*/
|
|
15874
|
-
_closePath(
|
|
15875
|
-
this._closeFile(
|
|
15876
|
-
const dir = sysPath2.dirname(
|
|
15877
|
-
this._getWatchedDir(dir).remove(sysPath2.basename(
|
|
16421
|
+
_closePath(path31) {
|
|
16422
|
+
this._closeFile(path31);
|
|
16423
|
+
const dir = sysPath2.dirname(path31);
|
|
16424
|
+
this._getWatchedDir(dir).remove(sysPath2.basename(path31));
|
|
15878
16425
|
}
|
|
15879
16426
|
/**
|
|
15880
16427
|
* Closes only file-specific watchers
|
|
15881
16428
|
*/
|
|
15882
|
-
_closeFile(
|
|
15883
|
-
const closers = this._closers.get(
|
|
16429
|
+
_closeFile(path31) {
|
|
16430
|
+
const closers = this._closers.get(path31);
|
|
15884
16431
|
if (!closers)
|
|
15885
16432
|
return;
|
|
15886
16433
|
closers.forEach((closer) => closer());
|
|
15887
|
-
this._closers.delete(
|
|
16434
|
+
this._closers.delete(path31);
|
|
15888
16435
|
}
|
|
15889
|
-
_addPathCloser(
|
|
16436
|
+
_addPathCloser(path31, closer) {
|
|
15890
16437
|
if (!closer)
|
|
15891
16438
|
return;
|
|
15892
|
-
let list = this._closers.get(
|
|
16439
|
+
let list = this._closers.get(path31);
|
|
15893
16440
|
if (!list) {
|
|
15894
16441
|
list = [];
|
|
15895
|
-
this._closers.set(
|
|
16442
|
+
this._closers.set(path31, list);
|
|
15896
16443
|
}
|
|
15897
16444
|
list.push(closer);
|
|
15898
16445
|
}
|
|
@@ -15922,7 +16469,7 @@ function watch(paths, options = {}) {
|
|
|
15922
16469
|
var esm_default = { watch, FSWatcher };
|
|
15923
16470
|
|
|
15924
16471
|
// modules/dev/hot-reload-client/index.ts
|
|
15925
|
-
var
|
|
16472
|
+
var import_path29 = __toESM(require("path"));
|
|
15926
16473
|
init_globals();
|
|
15927
16474
|
function setupHotReload({
|
|
15928
16475
|
app,
|
|
@@ -15964,7 +16511,7 @@ function setupHotReload({
|
|
|
15964
16511
|
});
|
|
15965
16512
|
});
|
|
15966
16513
|
console.log(`[hot-reload-server] \u2705 SSE endpoint registered at ${route}`);
|
|
15967
|
-
const resolvedProjectRoot = projectRoot ?
|
|
16514
|
+
const resolvedProjectRoot = projectRoot ? import_path29.default.resolve(projectRoot) : import_path29.default.dirname(import_path29.default.resolve(appDir));
|
|
15968
16515
|
const watcher = esm_default.watch(resolvedProjectRoot, {
|
|
15969
16516
|
ignoreInitial: true,
|
|
15970
16517
|
ignored: [
|
|
@@ -16004,11 +16551,11 @@ function setupHotReload({
|
|
|
16004
16551
|
let broadcastTimeout = null;
|
|
16005
16552
|
const BROADCAST_DEBOUNCE_MS = 300;
|
|
16006
16553
|
async function broadcastReload(reason, filePath) {
|
|
16007
|
-
const normalizedPath =
|
|
16554
|
+
const normalizedPath = import_path29.default.normalize(filePath);
|
|
16008
16555
|
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-")) {
|
|
16009
16556
|
return;
|
|
16010
16557
|
}
|
|
16011
|
-
const rel =
|
|
16558
|
+
const rel = import_path29.default.relative(appDir, filePath);
|
|
16012
16559
|
console.log(`[hot-reload] ${reason}: ${rel}`);
|
|
16013
16560
|
if (broadcastTimeout) {
|
|
16014
16561
|
clearTimeout(broadcastTimeout);
|
|
@@ -16058,9 +16605,9 @@ data: reload:${rel}
|
|
|
16058
16605
|
}
|
|
16059
16606
|
|
|
16060
16607
|
// modules/dev/hot-reload-server/index.ts
|
|
16061
|
-
var
|
|
16608
|
+
var import_path30 = __toESM(require("path"));
|
|
16062
16609
|
function clearAppRequireCache(appDir) {
|
|
16063
|
-
const appDirNormalized =
|
|
16610
|
+
const appDirNormalized = import_path30.default.resolve(appDir);
|
|
16064
16611
|
for (const id of Object.keys(require.cache)) {
|
|
16065
16612
|
if (id.startsWith(appDirNormalized)) {
|
|
16066
16613
|
delete require.cache[id];
|
|
@@ -16073,7 +16620,7 @@ init_globals();
|
|
|
16073
16620
|
function setupStaticFiles(app, projectRoot, config) {
|
|
16074
16621
|
if (!config) return;
|
|
16075
16622
|
const staticDir = getStaticDir(projectRoot, config);
|
|
16076
|
-
if (
|
|
16623
|
+
if (import_fs22.default.existsSync(staticDir)) {
|
|
16077
16624
|
app.use(
|
|
16078
16625
|
import_express.default.static(staticDir, {
|
|
16079
16626
|
// In production, add caching headers for better performance
|
|
@@ -16099,7 +16646,7 @@ function setupServer(app, options) {
|
|
|
16099
16646
|
var getRoutes = getRoutes2;
|
|
16100
16647
|
const { outDir, waitForBuild } = startClientBundler(projectRoot, "development");
|
|
16101
16648
|
const onFileChange = async (filePath) => {
|
|
16102
|
-
const rel =
|
|
16649
|
+
const rel = import_path31.default.relative(appDir, filePath);
|
|
16103
16650
|
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");
|
|
16104
16651
|
const isTsFile = filePath.endsWith(".ts") || filePath.endsWith(".tsx");
|
|
16105
16652
|
if (isTsFile) {
|
|
@@ -16135,8 +16682,8 @@ function setupServer(app, options) {
|
|
|
16135
16682
|
const wssRoutes = routeLoader.loadWssRoutes();
|
|
16136
16683
|
const notFoundPage = routeLoader.loadNotFoundRoute();
|
|
16137
16684
|
const errorPage = routeLoader.loadErrorRoute();
|
|
16138
|
-
const buildDir = config ? getBuildDir(projectRoot, config) :
|
|
16139
|
-
const clientOutDir =
|
|
16685
|
+
const buildDir = config ? getBuildDir(projectRoot, config) : import_path31.default.join(projectRoot, BUILD_FOLDER_NAME);
|
|
16686
|
+
const clientOutDir = import_path31.default.join(buildDir, "client");
|
|
16140
16687
|
app.use(
|
|
16141
16688
|
"/static",
|
|
16142
16689
|
import_express.default.static(clientOutDir, {
|
|
@@ -16263,11 +16810,11 @@ function createStrictRateLimiterFromConfig(config) {
|
|
|
16263
16810
|
}
|
|
16264
16811
|
|
|
16265
16812
|
// modules/server/middleware/auto-rate-limit.ts
|
|
16266
|
-
function matchesStrictPattern(
|
|
16813
|
+
function matchesStrictPattern(path31, patterns) {
|
|
16267
16814
|
for (const pattern of patterns) {
|
|
16268
16815
|
const regexPattern = pattern.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*").replace(/\//g, "\\/");
|
|
16269
16816
|
const regex = new RegExp(`^${regexPattern}$`);
|
|
16270
|
-
if (regex.test(
|
|
16817
|
+
if (regex.test(path31)) {
|
|
16271
16818
|
return true;
|
|
16272
16819
|
}
|
|
16273
16820
|
}
|
|
@@ -16302,8 +16849,31 @@ function getAutoRateLimiter(route, strictPatterns = [], rateLimitConfig) {
|
|
|
16302
16849
|
|
|
16303
16850
|
// modules/server/handlers/api.ts
|
|
16304
16851
|
async function handleApiRequest(options) {
|
|
16305
|
-
const { apiRoutes, urlPath, req, res, env = "dev" } = options;
|
|
16306
|
-
|
|
16852
|
+
const { apiRoutes, urlPath, req, res, env = "dev", rewriteLoader } = options;
|
|
16853
|
+
let finalUrlPath = urlPath;
|
|
16854
|
+
let extractedParams = {};
|
|
16855
|
+
if (rewriteLoader) {
|
|
16856
|
+
try {
|
|
16857
|
+
const compiledRewrites = await rewriteLoader.loadRewrites();
|
|
16858
|
+
const rewriteResult = await processRewrites(urlPath, compiledRewrites, req);
|
|
16859
|
+
if (rewriteResult) {
|
|
16860
|
+
finalUrlPath = rewriteResult.rewrittenPath;
|
|
16861
|
+
extractedParams = rewriteResult.extractedParams;
|
|
16862
|
+
Object.assign(req.query, extractedParams);
|
|
16863
|
+
if (!req.locals) {
|
|
16864
|
+
req.locals = {};
|
|
16865
|
+
}
|
|
16866
|
+
Object.assign(req.locals, extractedParams);
|
|
16867
|
+
}
|
|
16868
|
+
} catch (error) {
|
|
16869
|
+
const reqLogger = getRequestLogger(req);
|
|
16870
|
+
reqLogger.error("Error processing rewrites", error, {
|
|
16871
|
+
urlPath
|
|
16872
|
+
});
|
|
16873
|
+
}
|
|
16874
|
+
}
|
|
16875
|
+
finalUrlPath = finalUrlPath.replace(/\/$/, "") || "/";
|
|
16876
|
+
const matched = matchApiRoute(apiRoutes, finalUrlPath);
|
|
16307
16877
|
if (!matched) {
|
|
16308
16878
|
res.status(404).json({ error: "Not Found" });
|
|
16309
16879
|
return;
|
|
@@ -16324,9 +16894,13 @@ async function handleApiRequest(options) {
|
|
|
16324
16894
|
Response: (body = {}, status = 200) => res.status(status).json(body),
|
|
16325
16895
|
NotFound: (body = {}) => res.status(404).json(body),
|
|
16326
16896
|
params: sanitizedParams,
|
|
16327
|
-
pathname:
|
|
16897
|
+
pathname: finalUrlPath,
|
|
16898
|
+
// Use rewritten path
|
|
16328
16899
|
locals: {}
|
|
16329
16900
|
};
|
|
16901
|
+
if (extractedParams && Object.keys(extractedParams).length > 0) {
|
|
16902
|
+
Object.assign(ctx.locals, extractedParams);
|
|
16903
|
+
}
|
|
16330
16904
|
req.query = sanitizedQuery;
|
|
16331
16905
|
try {
|
|
16332
16906
|
const autoRateLimiter = getAutoRateLimiter(
|
|
@@ -16405,7 +16979,19 @@ async function handleApiRequest(options) {
|
|
|
16405
16979
|
|
|
16406
16980
|
// modules/server/routes.ts
|
|
16407
16981
|
init_globals();
|
|
16408
|
-
var
|
|
16982
|
+
var import_path32 = __toESM(require("path"));
|
|
16983
|
+
var cachedRewriteLoader = null;
|
|
16984
|
+
var cachedProjectRoot = null;
|
|
16985
|
+
var cachedIsDev = null;
|
|
16986
|
+
function getRewriteLoader(projectRoot, isDev) {
|
|
16987
|
+
if (cachedRewriteLoader && cachedProjectRoot === projectRoot && cachedIsDev === isDev) {
|
|
16988
|
+
return cachedRewriteLoader;
|
|
16989
|
+
}
|
|
16990
|
+
cachedRewriteLoader = createRewriteLoader(projectRoot, isDev);
|
|
16991
|
+
cachedProjectRoot = projectRoot;
|
|
16992
|
+
cachedIsDev = isDev;
|
|
16993
|
+
return cachedRewriteLoader;
|
|
16994
|
+
}
|
|
16409
16995
|
function setupRoutes(options) {
|
|
16410
16996
|
const {
|
|
16411
16997
|
app,
|
|
@@ -16420,8 +17006,9 @@ function setupRoutes(options) {
|
|
|
16420
17006
|
config
|
|
16421
17007
|
} = options;
|
|
16422
17008
|
const routeChunks = routeLoader.loadRouteChunks();
|
|
16423
|
-
const
|
|
16424
|
-
|
|
17009
|
+
const rewriteLoader = getRewriteLoader(projectRoot, isDev);
|
|
17010
|
+
const ssgOutDir = import_path32.default.join(
|
|
17011
|
+
config ? getBuildDir(projectRoot, config) : import_path32.default.join(projectRoot, BUILD_FOLDER_NAME),
|
|
16425
17012
|
"ssg"
|
|
16426
17013
|
);
|
|
16427
17014
|
app.all("/api/*", async (req, res) => {
|
|
@@ -16436,7 +17023,8 @@ function setupRoutes(options) {
|
|
|
16436
17023
|
res,
|
|
16437
17024
|
env: isDev ? "dev" : "prod",
|
|
16438
17025
|
strictRateLimitPatterns: strictPatterns,
|
|
16439
|
-
rateLimitConfig
|
|
17026
|
+
rateLimitConfig,
|
|
17027
|
+
rewriteLoader
|
|
16440
17028
|
});
|
|
16441
17029
|
});
|
|
16442
17030
|
app.get("*", async (req, res) => {
|
|
@@ -16459,7 +17047,8 @@ function setupRoutes(options) {
|
|
|
16459
17047
|
ssgOutDir,
|
|
16460
17048
|
theme: req.cookies?.theme || "light",
|
|
16461
17049
|
projectRoot,
|
|
16462
|
-
config
|
|
17050
|
+
config,
|
|
17051
|
+
rewriteLoader
|
|
16463
17052
|
});
|
|
16464
17053
|
});
|
|
16465
17054
|
}
|
|
@@ -17648,8 +18237,8 @@ var setupApplication = async ({
|
|
|
17648
18237
|
|
|
17649
18238
|
// src/server.ts
|
|
17650
18239
|
var import_dotenv2 = __toESM(require("dotenv"));
|
|
17651
|
-
var envPath =
|
|
17652
|
-
if (
|
|
18240
|
+
var envPath = import_path33.default.join(process.cwd(), ".env");
|
|
18241
|
+
if (import_fs23.default.existsSync(envPath)) {
|
|
17653
18242
|
import_dotenv2.default.config({ path: envPath });
|
|
17654
18243
|
} else {
|
|
17655
18244
|
import_dotenv2.default.config();
|
|
@@ -17670,8 +18259,8 @@ async function startServer(options = {}) {
|
|
|
17670
18259
|
}
|
|
17671
18260
|
const port = options.port ?? (process.env.PORT ? parseInt(process.env.PORT, 10) : void 0) ?? config.server.port;
|
|
17672
18261
|
const host = process.env.HOST ?? (!isDev ? "0.0.0.0" : void 0) ?? config.server.host;
|
|
17673
|
-
const appDir = options.appDir ?? (isDev ? getAppDir(projectRoot, config) :
|
|
17674
|
-
if (!isDev && !
|
|
18262
|
+
const appDir = options.appDir ?? (isDev ? getAppDir(projectRoot, config) : import_path33.default.join(getBuildDir(projectRoot, config), "server"));
|
|
18263
|
+
if (!isDev && !import_fs23.default.existsSync(appDir)) {
|
|
17675
18264
|
logger4.error("Compiled directory not found", void 0, {
|
|
17676
18265
|
buildDir: config.directories.build,
|
|
17677
18266
|
appDir,
|
|
@@ -17867,7 +18456,7 @@ async function run() {
|
|
|
17867
18456
|
}
|
|
17868
18457
|
const args = parseArgs(argv.slice(1));
|
|
17869
18458
|
const projectRoot = import_process.default.cwd();
|
|
17870
|
-
const appDir =
|
|
18459
|
+
const appDir = import_path34.default.resolve(projectRoot, args.appDir || "app");
|
|
17871
18460
|
const port = typeof args.port === "string" && args.port.trim().length > 0 ? Number(args.port) : 3e3;
|
|
17872
18461
|
switch (command) {
|
|
17873
18462
|
case "dev": {
|