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