@tanstack/router-core 1.167.1 → 1.167.3

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.
Files changed (164) hide show
  1. package/dist/cjs/Matches.cjs +15 -12
  2. package/dist/cjs/Matches.cjs.map +1 -1
  3. package/dist/cjs/_virtual/_rolldown/runtime.cjs +23 -0
  4. package/dist/cjs/config.cjs +9 -8
  5. package/dist/cjs/config.cjs.map +1 -1
  6. package/dist/cjs/defer.cjs +37 -21
  7. package/dist/cjs/defer.cjs.map +1 -1
  8. package/dist/cjs/index.cjs +87 -89
  9. package/dist/cjs/isServer/client.cjs +5 -3
  10. package/dist/cjs/isServer/client.cjs.map +1 -1
  11. package/dist/cjs/isServer/development.cjs +5 -3
  12. package/dist/cjs/isServer/development.cjs.map +1 -1
  13. package/dist/cjs/isServer/server.cjs +5 -3
  14. package/dist/cjs/isServer/server.cjs.map +1 -1
  15. package/dist/cjs/link.cjs +5 -4
  16. package/dist/cjs/link.cjs.map +1 -1
  17. package/dist/cjs/load-matches.cjs +622 -766
  18. package/dist/cjs/load-matches.cjs.map +1 -1
  19. package/dist/cjs/lru-cache.cjs +67 -64
  20. package/dist/cjs/lru-cache.cjs.map +1 -1
  21. package/dist/cjs/new-process-route-tree.cjs +707 -792
  22. package/dist/cjs/new-process-route-tree.cjs.map +1 -1
  23. package/dist/cjs/not-found.cjs +20 -7
  24. package/dist/cjs/not-found.cjs.map +1 -1
  25. package/dist/cjs/path.cjs +221 -232
  26. package/dist/cjs/path.cjs.map +1 -1
  27. package/dist/cjs/qss.cjs +62 -28
  28. package/dist/cjs/qss.cjs.map +1 -1
  29. package/dist/cjs/redirect.cjs +44 -30
  30. package/dist/cjs/redirect.cjs.map +1 -1
  31. package/dist/cjs/rewrite.cjs +56 -56
  32. package/dist/cjs/rewrite.cjs.map +1 -1
  33. package/dist/cjs/root.cjs +6 -4
  34. package/dist/cjs/root.cjs.map +1 -1
  35. package/dist/cjs/route.cjs +96 -105
  36. package/dist/cjs/route.cjs.map +1 -1
  37. package/dist/cjs/router.cjs +1154 -1524
  38. package/dist/cjs/router.cjs.map +1 -1
  39. package/dist/cjs/scroll-restoration.cjs +189 -207
  40. package/dist/cjs/scroll-restoration.cjs.map +1 -1
  41. package/dist/cjs/searchMiddleware.cjs +48 -37
  42. package/dist/cjs/searchMiddleware.cjs.map +1 -1
  43. package/dist/cjs/searchParams.cjs +57 -45
  44. package/dist/cjs/searchParams.cjs.map +1 -1
  45. package/dist/cjs/ssr/client.cjs +6 -8
  46. package/dist/cjs/ssr/constants.cjs +6 -5
  47. package/dist/cjs/ssr/constants.cjs.map +1 -1
  48. package/dist/cjs/ssr/createRequestHandler.cjs +41 -59
  49. package/dist/cjs/ssr/createRequestHandler.cjs.map +1 -1
  50. package/dist/cjs/ssr/handlerCallback.cjs +5 -4
  51. package/dist/cjs/ssr/handlerCallback.cjs.map +1 -1
  52. package/dist/cjs/ssr/headers.cjs +17 -26
  53. package/dist/cjs/ssr/headers.cjs.map +1 -1
  54. package/dist/cjs/ssr/json.cjs +8 -4
  55. package/dist/cjs/ssr/json.cjs.map +1 -1
  56. package/dist/cjs/ssr/serializer/RawStream.cjs +268 -268
  57. package/dist/cjs/ssr/serializer/RawStream.cjs.map +1 -1
  58. package/dist/cjs/ssr/serializer/ShallowErrorPlugin.cjs +31 -32
  59. package/dist/cjs/ssr/serializer/ShallowErrorPlugin.cjs.map +1 -1
  60. package/dist/cjs/ssr/serializer/seroval-plugins.cjs +12 -12
  61. package/dist/cjs/ssr/serializer/seroval-plugins.cjs.map +1 -1
  62. package/dist/cjs/ssr/serializer/transformer.cjs +45 -41
  63. package/dist/cjs/ssr/serializer/transformer.cjs.map +1 -1
  64. package/dist/cjs/ssr/server.cjs +12 -14
  65. package/dist/cjs/ssr/ssr-client.cjs +173 -211
  66. package/dist/cjs/ssr/ssr-client.cjs.map +1 -1
  67. package/dist/cjs/ssr/ssr-match-id.cjs +6 -5
  68. package/dist/cjs/ssr/ssr-match-id.cjs.map +1 -1
  69. package/dist/cjs/ssr/ssr-server.cjs +266 -300
  70. package/dist/cjs/ssr/ssr-server.cjs.map +1 -1
  71. package/dist/cjs/ssr/transformStreamWithRouter.cjs +317 -337
  72. package/dist/cjs/ssr/transformStreamWithRouter.cjs.map +1 -1
  73. package/dist/cjs/ssr/tsrScript.cjs +6 -4
  74. package/dist/cjs/ssr/tsrScript.cjs.map +1 -1
  75. package/dist/cjs/utils/batch.cjs +13 -13
  76. package/dist/cjs/utils/batch.cjs.map +1 -1
  77. package/dist/cjs/utils.cjs +274 -208
  78. package/dist/cjs/utils.cjs.map +1 -1
  79. package/dist/esm/Matches.js +16 -13
  80. package/dist/esm/Matches.js.map +1 -1
  81. package/dist/esm/config.js +10 -9
  82. package/dist/esm/config.js.map +1 -1
  83. package/dist/esm/defer.js +37 -22
  84. package/dist/esm/defer.js.map +1 -1
  85. package/dist/esm/index.js +12 -82
  86. package/dist/esm/isServer/client.js +6 -5
  87. package/dist/esm/isServer/client.js.map +1 -1
  88. package/dist/esm/isServer/development.js +6 -5
  89. package/dist/esm/isServer/development.js.map +1 -1
  90. package/dist/esm/isServer/server.js +6 -5
  91. package/dist/esm/isServer/server.js.map +1 -1
  92. package/dist/esm/link.js +6 -5
  93. package/dist/esm/link.js.map +1 -1
  94. package/dist/esm/load-matches.js +617 -765
  95. package/dist/esm/load-matches.js.map +1 -1
  96. package/dist/esm/lru-cache.js +68 -65
  97. package/dist/esm/lru-cache.js.map +1 -1
  98. package/dist/esm/new-process-route-tree.js +705 -797
  99. package/dist/esm/new-process-route-tree.js.map +1 -1
  100. package/dist/esm/not-found.js +21 -9
  101. package/dist/esm/not-found.js.map +1 -1
  102. package/dist/esm/path.js +220 -241
  103. package/dist/esm/path.js.map +1 -1
  104. package/dist/esm/qss.js +63 -30
  105. package/dist/esm/qss.js.map +1 -1
  106. package/dist/esm/redirect.js +45 -34
  107. package/dist/esm/redirect.js.map +1 -1
  108. package/dist/esm/rewrite.js +57 -60
  109. package/dist/esm/rewrite.js.map +1 -1
  110. package/dist/esm/root.js +7 -5
  111. package/dist/esm/root.js.map +1 -1
  112. package/dist/esm/route.js +92 -105
  113. package/dist/esm/route.js.map +1 -1
  114. package/dist/esm/router.js +1148 -1527
  115. package/dist/esm/router.js.map +1 -1
  116. package/dist/esm/scroll-restoration.js +188 -213
  117. package/dist/esm/scroll-restoration.js.map +1 -1
  118. package/dist/esm/searchMiddleware.js +48 -38
  119. package/dist/esm/searchMiddleware.js.map +1 -1
  120. package/dist/esm/searchParams.js +57 -48
  121. package/dist/esm/searchParams.js.map +1 -1
  122. package/dist/esm/ssr/client.js +1 -6
  123. package/dist/esm/ssr/constants.js +7 -7
  124. package/dist/esm/ssr/constants.js.map +1 -1
  125. package/dist/esm/ssr/createRequestHandler.js +39 -58
  126. package/dist/esm/ssr/createRequestHandler.js.map +1 -1
  127. package/dist/esm/ssr/handlerCallback.js +6 -5
  128. package/dist/esm/ssr/handlerCallback.js.map +1 -1
  129. package/dist/esm/ssr/headers.js +16 -26
  130. package/dist/esm/ssr/headers.js.map +1 -1
  131. package/dist/esm/ssr/json.js +9 -5
  132. package/dist/esm/ssr/json.js.map +1 -1
  133. package/dist/esm/ssr/serializer/RawStream.js +267 -273
  134. package/dist/esm/ssr/serializer/RawStream.js.map +1 -1
  135. package/dist/esm/ssr/serializer/ShallowErrorPlugin.js +31 -32
  136. package/dist/esm/ssr/serializer/ShallowErrorPlugin.js.map +1 -1
  137. package/dist/esm/ssr/serializer/seroval-plugins.js +10 -11
  138. package/dist/esm/ssr/serializer/seroval-plugins.js.map +1 -1
  139. package/dist/esm/ssr/serializer/transformer.js +44 -43
  140. package/dist/esm/ssr/serializer/transformer.js.map +1 -1
  141. package/dist/esm/ssr/server.js +2 -12
  142. package/dist/esm/ssr/ssr-client.js +169 -209
  143. package/dist/esm/ssr/ssr-client.js.map +1 -1
  144. package/dist/esm/ssr/ssr-match-id.js +7 -7
  145. package/dist/esm/ssr/ssr-match-id.js.map +1 -1
  146. package/dist/esm/ssr/ssr-server.js +262 -300
  147. package/dist/esm/ssr/ssr-server.js.map +1 -1
  148. package/dist/esm/ssr/transformStreamWithRouter.js +315 -338
  149. package/dist/esm/ssr/transformStreamWithRouter.js.map +1 -1
  150. package/dist/esm/ssr/tsrScript.js +6 -5
  151. package/dist/esm/ssr/tsrScript.js.map +1 -1
  152. package/dist/esm/utils/batch.js +13 -14
  153. package/dist/esm/utils/batch.js.map +1 -1
  154. package/dist/esm/utils.js +273 -224
  155. package/dist/esm/utils.js.map +1 -1
  156. package/package.json +2 -2
  157. package/src/load-matches.ts +4 -1
  158. package/src/router.ts +2 -1
  159. package/dist/cjs/index.cjs.map +0 -1
  160. package/dist/cjs/ssr/client.cjs.map +0 -1
  161. package/dist/cjs/ssr/server.cjs.map +0 -1
  162. package/dist/esm/index.js.map +0 -1
  163. package/dist/esm/ssr/client.js.map +0 -1
  164. package/dist/esm/ssr/server.js.map +0 -1
package/dist/cjs/path.cjs CHANGED
@@ -1,256 +1,244 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const isServer = require("@tanstack/router-core/isServer");
4
- const utils = require("./utils.cjs");
5
- const newProcessRouteTree = require("./new-process-route-tree.cjs");
1
+ require("./_virtual/_rolldown/runtime.cjs");
2
+ const require_utils = require("./utils.cjs");
3
+ const require_new_process_route_tree = require("./new-process-route-tree.cjs");
4
+ let _tanstack_router_core_isServer = require("@tanstack/router-core/isServer");
5
+ //#region src/path.ts
6
+ /** Join path segments, cleaning duplicate slashes between parts. */
6
7
  function joinPaths(paths) {
7
- return cleanPath(
8
- paths.filter((val) => {
9
- return val !== void 0;
10
- }).join("/")
11
- );
8
+ return cleanPath(paths.filter((val) => {
9
+ return val !== void 0;
10
+ }).join("/"));
12
11
  }
12
+ /** Remove repeated slashes from a path string. */
13
13
  function cleanPath(path) {
14
- return path.replace(/\/{2,}/g, "/");
14
+ return path.replace(/\/{2,}/g, "/");
15
15
  }
16
+ /** Trim leading slashes (except preserving root '/'). */
16
17
  function trimPathLeft(path) {
17
- return path === "/" ? path : path.replace(/^\/{1,}/, "");
18
+ return path === "/" ? path : path.replace(/^\/{1,}/, "");
18
19
  }
20
+ /** Trim trailing slashes (except preserving root '/'). */
19
21
  function trimPathRight(path) {
20
- const len = path.length;
21
- return len > 1 && path[len - 1] === "/" ? path.replace(/\/{1,}$/, "") : path;
22
+ const len = path.length;
23
+ return len > 1 && path[len - 1] === "/" ? path.replace(/\/{1,}$/, "") : path;
22
24
  }
25
+ /** Trim both leading and trailing slashes. */
23
26
  function trimPath(path) {
24
- return trimPathRight(trimPathLeft(path));
27
+ return trimPathRight(trimPathLeft(path));
25
28
  }
29
+ /** Remove a trailing slash from value when appropriate for comparisons. */
26
30
  function removeTrailingSlash(value, basepath) {
27
- if (value?.endsWith("/") && value !== "/" && value !== `${basepath}/`) {
28
- return value.slice(0, -1);
29
- }
30
- return value;
31
+ if (value?.endsWith("/") && value !== "/" && value !== `${basepath}/`) return value.slice(0, -1);
32
+ return value;
31
33
  }
34
+ /**
35
+ * Compare two pathnames for exact equality after normalizing trailing slashes
36
+ * relative to the provided `basepath`.
37
+ */
32
38
  function exactPathTest(pathName1, pathName2, basepath) {
33
- return removeTrailingSlash(pathName1, basepath) === removeTrailingSlash(pathName2, basepath);
39
+ return removeTrailingSlash(pathName1, basepath) === removeTrailingSlash(pathName2, basepath);
34
40
  }
35
- function resolvePath({
36
- base,
37
- to,
38
- trailingSlash = "never",
39
- cache
40
- }) {
41
- const isAbsolute = to.startsWith("/");
42
- const isBase = !isAbsolute && to === ".";
43
- let key;
44
- if (cache) {
45
- key = isAbsolute ? to : isBase ? base : base + "\0" + to;
46
- const cached = cache.get(key);
47
- if (cached) return cached;
48
- }
49
- let baseSegments;
50
- if (isBase) {
51
- baseSegments = base.split("/");
52
- } else if (isAbsolute) {
53
- baseSegments = to.split("/");
54
- } else {
55
- baseSegments = base.split("/");
56
- while (baseSegments.length > 1 && utils.last(baseSegments) === "") {
57
- baseSegments.pop();
58
- }
59
- const toSegments = to.split("/");
60
- for (let index = 0, length = toSegments.length; index < length; index++) {
61
- const value = toSegments[index];
62
- if (value === "") {
63
- if (!index) {
64
- baseSegments = [value];
65
- } else if (index === length - 1) {
66
- baseSegments.push(value);
67
- } else ;
68
- } else if (value === "..") {
69
- baseSegments.pop();
70
- } else if (value === ".") ;
71
- else {
72
- baseSegments.push(value);
73
- }
74
- }
75
- }
76
- if (baseSegments.length > 1) {
77
- if (utils.last(baseSegments) === "") {
78
- if (trailingSlash === "never") {
79
- baseSegments.pop();
80
- }
81
- } else if (trailingSlash === "always") {
82
- baseSegments.push("");
83
- }
84
- }
85
- let segment;
86
- let joined = "";
87
- for (let i = 0; i < baseSegments.length; i++) {
88
- if (i > 0) joined += "/";
89
- const part = baseSegments[i];
90
- if (!part) continue;
91
- segment = newProcessRouteTree.parseSegment(part, 0, segment);
92
- const kind = segment[0];
93
- if (kind === newProcessRouteTree.SEGMENT_TYPE_PATHNAME) {
94
- joined += part;
95
- continue;
96
- }
97
- const end = segment[5];
98
- const prefix = part.substring(0, segment[1]);
99
- const suffix = part.substring(segment[4], end);
100
- const value = part.substring(segment[2], segment[3]);
101
- if (kind === newProcessRouteTree.SEGMENT_TYPE_PARAM) {
102
- joined += prefix || suffix ? `${prefix}{$${value}}${suffix}` : `$${value}`;
103
- } else if (kind === newProcessRouteTree.SEGMENT_TYPE_WILDCARD) {
104
- joined += prefix || suffix ? `${prefix}{$}${suffix}` : "$";
105
- } else {
106
- joined += `${prefix}{-$${value}}${suffix}`;
107
- }
108
- }
109
- joined = cleanPath(joined);
110
- const result = joined || "/";
111
- if (key && cache) cache.set(key, result);
112
- return result;
41
+ /**
42
+ * Resolve a destination path against a base, honoring trailing-slash policy
43
+ * and supporting relative segments (`.`/`..`) and absolute `to` values.
44
+ */
45
+ function resolvePath({ base, to, trailingSlash = "never", cache }) {
46
+ const isAbsolute = to.startsWith("/");
47
+ const isBase = !isAbsolute && to === ".";
48
+ let key;
49
+ if (cache) {
50
+ key = isAbsolute ? to : isBase ? base : base + "\0" + to;
51
+ const cached = cache.get(key);
52
+ if (cached) return cached;
53
+ }
54
+ let baseSegments;
55
+ if (isBase) baseSegments = base.split("/");
56
+ else if (isAbsolute) baseSegments = to.split("/");
57
+ else {
58
+ baseSegments = base.split("/");
59
+ while (baseSegments.length > 1 && require_utils.last(baseSegments) === "") baseSegments.pop();
60
+ const toSegments = to.split("/");
61
+ for (let index = 0, length = toSegments.length; index < length; index++) {
62
+ const value = toSegments[index];
63
+ if (value === "") {
64
+ if (!index) baseSegments = [value];
65
+ else if (index === length - 1) baseSegments.push(value);
66
+ } else if (value === "..") baseSegments.pop();
67
+ else if (value === ".") {} else baseSegments.push(value);
68
+ }
69
+ }
70
+ if (baseSegments.length > 1) {
71
+ if (require_utils.last(baseSegments) === "") {
72
+ if (trailingSlash === "never") baseSegments.pop();
73
+ } else if (trailingSlash === "always") baseSegments.push("");
74
+ }
75
+ let segment;
76
+ let joined = "";
77
+ for (let i = 0; i < baseSegments.length; i++) {
78
+ if (i > 0) joined += "/";
79
+ const part = baseSegments[i];
80
+ if (!part) continue;
81
+ segment = require_new_process_route_tree.parseSegment(part, 0, segment);
82
+ const kind = segment[0];
83
+ if (kind === 0) {
84
+ joined += part;
85
+ continue;
86
+ }
87
+ const end = segment[5];
88
+ const prefix = part.substring(0, segment[1]);
89
+ const suffix = part.substring(segment[4], end);
90
+ const value = part.substring(segment[2], segment[3]);
91
+ if (kind === 1) joined += prefix || suffix ? `${prefix}{$${value}}${suffix}` : `$${value}`;
92
+ else if (kind === 2) joined += prefix || suffix ? `${prefix}{$}${suffix}` : "$";
93
+ else joined += `${prefix}{-$${value}}${suffix}`;
94
+ }
95
+ joined = cleanPath(joined);
96
+ const result = joined || "/";
97
+ if (key && cache) cache.set(key, result);
98
+ return result;
113
99
  }
100
+ /**
101
+ * Create a pre-compiled decode config from allowed characters.
102
+ * This should be called once at router initialization.
103
+ */
114
104
  function compileDecodeCharMap(pathParamsAllowedCharacters) {
115
- const charMap = new Map(
116
- pathParamsAllowedCharacters.map((char) => [encodeURIComponent(char), char])
117
- );
118
- const pattern = Array.from(charMap.keys()).map((key) => key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
119
- const regex = new RegExp(pattern, "g");
120
- return (encoded) => encoded.replace(regex, (match) => charMap.get(match) ?? match);
105
+ const charMap = new Map(pathParamsAllowedCharacters.map((char) => [encodeURIComponent(char), char]));
106
+ const pattern = Array.from(charMap.keys()).map((key) => key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
107
+ const regex = new RegExp(pattern, "g");
108
+ return (encoded) => encoded.replace(regex, (match) => charMap.get(match) ?? match);
121
109
  }
122
110
  function encodeParam(key, params, decoder) {
123
- const value = params[key];
124
- if (typeof value !== "string") return value;
125
- if (key === "_splat") {
126
- if (/^[a-zA-Z0-9\-._~!/]*$/.test(value)) return value;
127
- return value.split("/").map((segment) => encodePathParam(segment, decoder)).join("/");
128
- } else {
129
- return encodePathParam(value, decoder);
130
- }
111
+ const value = params[key];
112
+ if (typeof value !== "string") return value;
113
+ if (key === "_splat") {
114
+ if (/^[a-zA-Z0-9\-._~!/]*$/.test(value)) return value;
115
+ return value.split("/").map((segment) => encodePathParam(segment, decoder)).join("/");
116
+ } else return encodePathParam(value, decoder);
131
117
  }
132
- function interpolatePath({
133
- path,
134
- params,
135
- decoder,
136
- // `server` is marked @internal and stripped from .d.ts by `stripInternal`.
137
- // We avoid destructuring it in the function signature so the emitted
138
- // declaration doesn't reference a property that no longer exists.
139
- ...rest
140
- }) {
141
- let isMissingParams = false;
142
- const usedParams = /* @__PURE__ */ Object.create(null);
143
- if (!path || path === "/")
144
- return { interpolatedPath: "/", usedParams, isMissingParams };
145
- if (!path.includes("$"))
146
- return { interpolatedPath: path, usedParams, isMissingParams };
147
- if (isServer.isServer ?? rest.server) {
148
- if (path.indexOf("{") === -1) {
149
- const length2 = path.length;
150
- let cursor2 = 0;
151
- let joined2 = "";
152
- while (cursor2 < length2) {
153
- while (cursor2 < length2 && path.charCodeAt(cursor2) === 47) cursor2++;
154
- if (cursor2 >= length2) break;
155
- const start = cursor2;
156
- let end = path.indexOf("/", cursor2);
157
- if (end === -1) end = length2;
158
- cursor2 = end;
159
- const part = path.substring(start, end);
160
- if (!part) continue;
161
- if (part.charCodeAt(0) === 36) {
162
- if (part.length === 1) {
163
- const splat = params._splat;
164
- usedParams._splat = splat;
165
- usedParams["*"] = splat;
166
- if (!splat) {
167
- isMissingParams = true;
168
- continue;
169
- }
170
- const value = encodeParam("_splat", params, decoder);
171
- joined2 += "/" + value;
172
- } else {
173
- const key = part.substring(1);
174
- if (!isMissingParams && !(key in params)) {
175
- isMissingParams = true;
176
- }
177
- usedParams[key] = params[key];
178
- const value = encodeParam(key, params, decoder) ?? "undefined";
179
- joined2 += "/" + value;
180
- }
181
- } else {
182
- joined2 += "/" + part;
183
- }
184
- }
185
- if (path.endsWith("/")) joined2 += "/";
186
- const interpolatedPath2 = joined2 || "/";
187
- return { usedParams, interpolatedPath: interpolatedPath2, isMissingParams };
188
- }
189
- }
190
- const length = path.length;
191
- let cursor = 0;
192
- let segment;
193
- let joined = "";
194
- while (cursor < length) {
195
- const start = cursor;
196
- segment = newProcessRouteTree.parseSegment(path, start, segment);
197
- const end = segment[5];
198
- cursor = end + 1;
199
- if (start === end) continue;
200
- const kind = segment[0];
201
- if (kind === newProcessRouteTree.SEGMENT_TYPE_PATHNAME) {
202
- joined += "/" + path.substring(start, end);
203
- continue;
204
- }
205
- if (kind === newProcessRouteTree.SEGMENT_TYPE_WILDCARD) {
206
- const splat = params._splat;
207
- usedParams._splat = splat;
208
- usedParams["*"] = splat;
209
- const prefix = path.substring(start, segment[1]);
210
- const suffix = path.substring(segment[4], end);
211
- if (!splat) {
212
- isMissingParams = true;
213
- if (prefix || suffix) {
214
- joined += "/" + prefix + suffix;
215
- }
216
- continue;
217
- }
218
- const value = encodeParam("_splat", params, decoder);
219
- joined += "/" + prefix + value + suffix;
220
- continue;
221
- }
222
- if (kind === newProcessRouteTree.SEGMENT_TYPE_PARAM) {
223
- const key = path.substring(segment[2], segment[3]);
224
- if (!isMissingParams && !(key in params)) {
225
- isMissingParams = true;
226
- }
227
- usedParams[key] = params[key];
228
- const prefix = path.substring(start, segment[1]);
229
- const suffix = path.substring(segment[4], end);
230
- const value = encodeParam(key, params, decoder) ?? "undefined";
231
- joined += "/" + prefix + value + suffix;
232
- continue;
233
- }
234
- if (kind === newProcessRouteTree.SEGMENT_TYPE_OPTIONAL_PARAM) {
235
- const key = path.substring(segment[2], segment[3]);
236
- const valueRaw = params[key];
237
- if (valueRaw == null) continue;
238
- usedParams[key] = valueRaw;
239
- const prefix = path.substring(start, segment[1]);
240
- const suffix = path.substring(segment[4], end);
241
- const value = encodeParam(key, params, decoder) ?? "";
242
- joined += "/" + prefix + value + suffix;
243
- continue;
244
- }
245
- }
246
- if (path.endsWith("/")) joined += "/";
247
- const interpolatedPath = joined || "/";
248
- return { usedParams, interpolatedPath, isMissingParams };
118
+ /**
119
+ * Interpolate params and wildcards into a route path template.
120
+ *
121
+ * - Encodes params safely (configurable allowed characters)
122
+ * - Supports `{-$optional}` segments, `{prefix{$id}suffix}` and `{$}` wildcards
123
+ */
124
+ function interpolatePath({ path, params, decoder, ...rest }) {
125
+ let isMissingParams = false;
126
+ const usedParams = Object.create(null);
127
+ if (!path || path === "/") return {
128
+ interpolatedPath: "/",
129
+ usedParams,
130
+ isMissingParams
131
+ };
132
+ if (!path.includes("$")) return {
133
+ interpolatedPath: path,
134
+ usedParams,
135
+ isMissingParams
136
+ };
137
+ if (_tanstack_router_core_isServer.isServer ?? rest.server) {
138
+ if (path.indexOf("{") === -1) {
139
+ const length = path.length;
140
+ let cursor = 0;
141
+ let joined = "";
142
+ while (cursor < length) {
143
+ while (cursor < length && path.charCodeAt(cursor) === 47) cursor++;
144
+ if (cursor >= length) break;
145
+ const start = cursor;
146
+ let end = path.indexOf("/", cursor);
147
+ if (end === -1) end = length;
148
+ cursor = end;
149
+ const part = path.substring(start, end);
150
+ if (!part) continue;
151
+ if (part.charCodeAt(0) === 36) if (part.length === 1) {
152
+ const splat = params._splat;
153
+ usedParams._splat = splat;
154
+ usedParams["*"] = splat;
155
+ if (!splat) {
156
+ isMissingParams = true;
157
+ continue;
158
+ }
159
+ const value = encodeParam("_splat", params, decoder);
160
+ joined += "/" + value;
161
+ } else {
162
+ const key = part.substring(1);
163
+ if (!isMissingParams && !(key in params)) isMissingParams = true;
164
+ usedParams[key] = params[key];
165
+ const value = encodeParam(key, params, decoder) ?? "undefined";
166
+ joined += "/" + value;
167
+ }
168
+ else joined += "/" + part;
169
+ }
170
+ if (path.endsWith("/")) joined += "/";
171
+ return {
172
+ usedParams,
173
+ interpolatedPath: joined || "/",
174
+ isMissingParams
175
+ };
176
+ }
177
+ }
178
+ const length = path.length;
179
+ let cursor = 0;
180
+ let segment;
181
+ let joined = "";
182
+ while (cursor < length) {
183
+ const start = cursor;
184
+ segment = require_new_process_route_tree.parseSegment(path, start, segment);
185
+ const end = segment[5];
186
+ cursor = end + 1;
187
+ if (start === end) continue;
188
+ const kind = segment[0];
189
+ if (kind === 0) {
190
+ joined += "/" + path.substring(start, end);
191
+ continue;
192
+ }
193
+ if (kind === 2) {
194
+ const splat = params._splat;
195
+ usedParams._splat = splat;
196
+ usedParams["*"] = splat;
197
+ const prefix = path.substring(start, segment[1]);
198
+ const suffix = path.substring(segment[4], end);
199
+ if (!splat) {
200
+ isMissingParams = true;
201
+ if (prefix || suffix) joined += "/" + prefix + suffix;
202
+ continue;
203
+ }
204
+ const value = encodeParam("_splat", params, decoder);
205
+ joined += "/" + prefix + value + suffix;
206
+ continue;
207
+ }
208
+ if (kind === 1) {
209
+ const key = path.substring(segment[2], segment[3]);
210
+ if (!isMissingParams && !(key in params)) isMissingParams = true;
211
+ usedParams[key] = params[key];
212
+ const prefix = path.substring(start, segment[1]);
213
+ const suffix = path.substring(segment[4], end);
214
+ const value = encodeParam(key, params, decoder) ?? "undefined";
215
+ joined += "/" + prefix + value + suffix;
216
+ continue;
217
+ }
218
+ if (kind === 3) {
219
+ const key = path.substring(segment[2], segment[3]);
220
+ const valueRaw = params[key];
221
+ if (valueRaw == null) continue;
222
+ usedParams[key] = valueRaw;
223
+ const prefix = path.substring(start, segment[1]);
224
+ const suffix = path.substring(segment[4], end);
225
+ const value = encodeParam(key, params, decoder) ?? "";
226
+ joined += "/" + prefix + value + suffix;
227
+ continue;
228
+ }
229
+ }
230
+ if (path.endsWith("/")) joined += "/";
231
+ return {
232
+ usedParams,
233
+ interpolatedPath: joined || "/",
234
+ isMissingParams
235
+ };
249
236
  }
250
237
  function encodePathParam(value, decoder) {
251
- const encoded = encodeURIComponent(value);
252
- return decoder?.(encoded) ?? encoded;
238
+ const encoded = encodeURIComponent(value);
239
+ return decoder?.(encoded) ?? encoded;
253
240
  }
241
+ //#endregion
254
242
  exports.cleanPath = cleanPath;
255
243
  exports.compileDecodeCharMap = compileDecodeCharMap;
256
244
  exports.exactPathTest = exactPathTest;
@@ -261,4 +249,5 @@ exports.resolvePath = resolvePath;
261
249
  exports.trimPath = trimPath;
262
250
  exports.trimPathLeft = trimPathLeft;
263
251
  exports.trimPathRight = trimPathRight;
264
- //# sourceMappingURL=path.cjs.map
252
+
253
+ //# sourceMappingURL=path.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"path.cjs","sources":["../../src/path.ts"],"sourcesContent":["import { isServer } from '@tanstack/router-core/isServer'\nimport { last } from './utils'\nimport {\n SEGMENT_TYPE_OPTIONAL_PARAM,\n SEGMENT_TYPE_PARAM,\n SEGMENT_TYPE_PATHNAME,\n SEGMENT_TYPE_WILDCARD,\n parseSegment,\n} from './new-process-route-tree'\nimport type { LRUCache } from './lru-cache'\n\n/** Join path segments, cleaning duplicate slashes between parts. */\nexport function joinPaths(paths: Array<string | undefined>) {\n return cleanPath(\n paths\n .filter((val) => {\n return val !== undefined\n })\n .join('/'),\n )\n}\n\n/** Remove repeated slashes from a path string. */\nexport function cleanPath(path: string) {\n // remove double slashes\n return path.replace(/\\/{2,}/g, '/')\n}\n\n/** Trim leading slashes (except preserving root '/'). */\nexport function trimPathLeft(path: string) {\n return path === '/' ? path : path.replace(/^\\/{1,}/, '')\n}\n\n/** Trim trailing slashes (except preserving root '/'). */\nexport function trimPathRight(path: string) {\n const len = path.length\n return len > 1 && path[len - 1] === '/' ? path.replace(/\\/{1,}$/, '') : path\n}\n\n/** Trim both leading and trailing slashes. */\nexport function trimPath(path: string) {\n return trimPathRight(trimPathLeft(path))\n}\n\n/** Remove a trailing slash from value when appropriate for comparisons. */\nexport function removeTrailingSlash(value: string, basepath: string): string {\n if (value?.endsWith('/') && value !== '/' && value !== `${basepath}/`) {\n return value.slice(0, -1)\n }\n return value\n}\n\n// intended to only compare path name\n// see the usage in the isActive under useLinkProps\n// /sample/path1 = /sample/path1/\n// /sample/path1/some <> /sample/path1\n/**\n * Compare two pathnames for exact equality after normalizing trailing slashes\n * relative to the provided `basepath`.\n */\nexport function exactPathTest(\n pathName1: string,\n pathName2: string,\n basepath: string,\n): boolean {\n return (\n removeTrailingSlash(pathName1, basepath) ===\n removeTrailingSlash(pathName2, basepath)\n )\n}\n\n// When resolving relative paths, we treat all paths as if they are trailing slash\n// documents. All trailing slashes are removed after the path is resolved.\n// Here are a few examples:\n//\n// /a/b/c + ./d = /a/b/c/d\n// /a/b/c + ../d = /a/b/d\n// /a/b/c + ./d/ = /a/b/c/d\n// /a/b/c + ../d/ = /a/b/d\n// /a/b/c + ./ = /a/b/c\n//\n// Absolute paths that start with `/` short circuit the resolution process to the root\n// path.\n//\n// Here are some examples:\n//\n// /a/b/c + /d = /d\n// /a/b/c + /d/ = /d\n// /a/b/c + / = /\n//\n// Non-.-prefixed paths are still treated as relative paths, resolved like `./`\n//\n// Here are some examples:\n//\n// /a/b/c + d = /a/b/c/d\n// /a/b/c + d/ = /a/b/c/d\n// /a/b/c + d/e = /a/b/c/d/e\ninterface ResolvePathOptions {\n base: string\n to: string\n trailingSlash?: 'always' | 'never' | 'preserve'\n cache?: LRUCache<string, string>\n}\n\n/**\n * Resolve a destination path against a base, honoring trailing-slash policy\n * and supporting relative segments (`.`/`..`) and absolute `to` values.\n */\nexport function resolvePath({\n base,\n to,\n trailingSlash = 'never',\n cache,\n}: ResolvePathOptions) {\n const isAbsolute = to.startsWith('/')\n const isBase = !isAbsolute && to === '.'\n\n let key\n if (cache) {\n // `trailingSlash` is static per router, so it doesn't need to be part of the cache key\n key = isAbsolute ? to : isBase ? base : base + '\\0' + to\n const cached = cache.get(key)\n if (cached) return cached\n }\n\n let baseSegments: Array<string>\n if (isBase) {\n baseSegments = base.split('/')\n } else if (isAbsolute) {\n baseSegments = to.split('/')\n } else {\n baseSegments = base.split('/')\n while (baseSegments.length > 1 && last(baseSegments) === '') {\n baseSegments.pop()\n }\n\n const toSegments = to.split('/')\n for (let index = 0, length = toSegments.length; index < length; index++) {\n const value = toSegments[index]!\n if (value === '') {\n if (!index) {\n // Leading slash\n baseSegments = [value]\n } else if (index === length - 1) {\n // Trailing Slash\n baseSegments.push(value)\n } else {\n // ignore inter-slashes\n }\n } else if (value === '..') {\n baseSegments.pop()\n } else if (value === '.') {\n // ignore\n } else {\n baseSegments.push(value)\n }\n }\n }\n\n if (baseSegments.length > 1) {\n if (last(baseSegments) === '') {\n if (trailingSlash === 'never') {\n baseSegments.pop()\n }\n } else if (trailingSlash === 'always') {\n baseSegments.push('')\n }\n }\n\n let segment\n let joined = ''\n for (let i = 0; i < baseSegments.length; i++) {\n if (i > 0) joined += '/'\n const part = baseSegments[i]!\n if (!part) continue\n segment = parseSegment(part, 0, segment)\n const kind = segment[0]\n if (kind === SEGMENT_TYPE_PATHNAME) {\n joined += part\n continue\n }\n const end = segment[5]\n const prefix = part.substring(0, segment[1])\n const suffix = part.substring(segment[4], end)\n const value = part.substring(segment[2], segment[3])\n if (kind === SEGMENT_TYPE_PARAM) {\n joined += prefix || suffix ? `${prefix}{$${value}}${suffix}` : `$${value}`\n } else if (kind === SEGMENT_TYPE_WILDCARD) {\n joined += prefix || suffix ? `${prefix}{$}${suffix}` : '$'\n } else {\n // SEGMENT_TYPE_OPTIONAL_PARAM\n joined += `${prefix}{-$${value}}${suffix}`\n }\n }\n joined = cleanPath(joined)\n const result = joined || '/'\n if (key && cache) cache.set(key, result)\n return result\n}\n\n/**\n * Create a pre-compiled decode config from allowed characters.\n * This should be called once at router initialization.\n */\nexport function compileDecodeCharMap(\n pathParamsAllowedCharacters: ReadonlyArray<string>,\n) {\n const charMap = new Map(\n pathParamsAllowedCharacters.map((char) => [encodeURIComponent(char), char]),\n )\n // Escape special regex characters and join with |\n const pattern = Array.from(charMap.keys())\n .map((key) => key.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'))\n .join('|')\n const regex = new RegExp(pattern, 'g')\n return (encoded: string) =>\n encoded.replace(regex, (match) => charMap.get(match) ?? match)\n}\n\ninterface InterpolatePathOptions {\n path?: string\n params: Record<string, unknown>\n /**\n * A function that decodes a path parameter value.\n * Obtained from `compileDecodeCharMap(pathParamsAllowedCharacters)`.\n */\n decoder?: (encoded: string) => string\n /**\n * @internal\n * For testing only, in development mode we use the router.isServer value\n */\n server?: boolean\n}\n\ntype InterPolatePathResult = {\n interpolatedPath: string\n usedParams: Record<string, unknown>\n isMissingParams: boolean // true if any params were not available when being looked up in the params object\n}\n\nfunction encodeParam(\n key: string,\n params: InterpolatePathOptions['params'],\n decoder: InterpolatePathOptions['decoder'],\n): any {\n const value = params[key]\n if (typeof value !== 'string') return value\n\n if (key === '_splat') {\n // Early return if value only contains URL-safe characters (performance optimization)\n if (/^[a-zA-Z0-9\\-._~!/]*$/.test(value)) return value\n // the splat/catch-all routes shouldn't have the '/' encoded out\n // Use encodeURIComponent for each segment to properly encode spaces,\n // plus signs, and other special characters that encodeURI leaves unencoded\n return value\n .split('/')\n .map((segment) => encodePathParam(segment, decoder))\n .join('/')\n } else {\n return encodePathParam(value, decoder)\n }\n}\n\n/**\n * Interpolate params and wildcards into a route path template.\n *\n * - Encodes params safely (configurable allowed characters)\n * - Supports `{-$optional}` segments, `{prefix{$id}suffix}` and `{$}` wildcards\n */\nexport function interpolatePath({\n path,\n params,\n decoder,\n // `server` is marked @internal and stripped from .d.ts by `stripInternal`.\n // We avoid destructuring it in the function signature so the emitted\n // declaration doesn't reference a property that no longer exists.\n ...rest\n}: InterpolatePathOptions): InterPolatePathResult {\n // Tracking if any params are missing in the `params` object\n // when interpolating the path\n let isMissingParams = false\n const usedParams: Record<string, unknown> = Object.create(null)\n\n if (!path || path === '/')\n return { interpolatedPath: '/', usedParams, isMissingParams }\n if (!path.includes('$'))\n return { interpolatedPath: path, usedParams, isMissingParams }\n\n if (isServer ?? rest.server) {\n // Fast path for common templates like `/posts/$id` or `/files/$`.\n // Braced segments (`{...}`) are more complex (prefix/suffix/optional) and are\n // handled by the general parser below.\n if (path.indexOf('{') === -1) {\n const length = path.length\n let cursor = 0\n let joined = ''\n\n while (cursor < length) {\n // Skip slashes between segments. '/' code is 47\n while (cursor < length && path.charCodeAt(cursor) === 47) cursor++\n if (cursor >= length) break\n\n const start = cursor\n let end = path.indexOf('/', cursor)\n if (end === -1) end = length\n cursor = end\n\n const part = path.substring(start, end)\n if (!part) continue\n\n // `$id` or `$` (splat). '$' code is 36\n if (part.charCodeAt(0) === 36) {\n if (part.length === 1) {\n const splat = params._splat\n usedParams._splat = splat\n // TODO: Deprecate *\n usedParams['*'] = splat\n\n if (!splat) {\n isMissingParams = true\n continue\n }\n\n const value = encodeParam('_splat', params, decoder)\n joined += '/' + value\n } else {\n const key = part.substring(1)\n if (!isMissingParams && !(key in params)) {\n isMissingParams = true\n }\n usedParams[key] = params[key]\n\n const value = encodeParam(key, params, decoder) ?? 'undefined'\n joined += '/' + value\n }\n } else {\n joined += '/' + part\n }\n }\n\n if (path.endsWith('/')) joined += '/'\n\n const interpolatedPath = joined || '/'\n return { usedParams, interpolatedPath, isMissingParams }\n }\n }\n\n const length = path.length\n let cursor = 0\n let segment\n let joined = ''\n while (cursor < length) {\n const start = cursor\n segment = parseSegment(path, start, segment)\n const end = segment[5]\n cursor = end + 1\n\n if (start === end) continue\n\n const kind = segment[0]\n\n if (kind === SEGMENT_TYPE_PATHNAME) {\n joined += '/' + path.substring(start, end)\n continue\n }\n\n if (kind === SEGMENT_TYPE_WILDCARD) {\n const splat = params._splat\n usedParams._splat = splat\n // TODO: Deprecate *\n usedParams['*'] = splat\n\n const prefix = path.substring(start, segment[1])\n const suffix = path.substring(segment[4], end)\n\n // Check if _splat parameter is missing. _splat could be missing if undefined or an empty string or some other falsy value.\n if (!splat) {\n isMissingParams = true\n // For missing splat parameters, just return the prefix and suffix without the wildcard\n // If there is a prefix or suffix, return them joined, otherwise omit the segment\n if (prefix || suffix) {\n joined += '/' + prefix + suffix\n }\n continue\n }\n\n const value = encodeParam('_splat', params, decoder)\n joined += '/' + prefix + value + suffix\n continue\n }\n\n if (kind === SEGMENT_TYPE_PARAM) {\n const key = path.substring(segment[2], segment[3])\n if (!isMissingParams && !(key in params)) {\n isMissingParams = true\n }\n usedParams[key] = params[key]\n\n const prefix = path.substring(start, segment[1])\n const suffix = path.substring(segment[4], end)\n const value = encodeParam(key, params, decoder) ?? 'undefined'\n joined += '/' + prefix + value + suffix\n continue\n }\n\n if (kind === SEGMENT_TYPE_OPTIONAL_PARAM) {\n const key = path.substring(segment[2], segment[3])\n const valueRaw = params[key]\n\n // Check if optional parameter is missing or undefined\n if (valueRaw == null) continue\n\n usedParams[key] = valueRaw\n\n const prefix = path.substring(start, segment[1])\n const suffix = path.substring(segment[4], end)\n const value = encodeParam(key, params, decoder) ?? ''\n joined += '/' + prefix + value + suffix\n continue\n }\n }\n\n if (path.endsWith('/')) joined += '/'\n\n const interpolatedPath = joined || '/'\n\n return { usedParams, interpolatedPath, isMissingParams }\n}\n\nfunction encodePathParam(\n value: string,\n decoder?: InterpolatePathOptions['decoder'],\n) {\n const encoded = encodeURIComponent(value)\n return decoder?.(encoded) ?? encoded\n}\n"],"names":["last","parseSegment","SEGMENT_TYPE_PATHNAME","SEGMENT_TYPE_PARAM","SEGMENT_TYPE_WILDCARD","isServer","length","cursor","joined","interpolatedPath","SEGMENT_TYPE_OPTIONAL_PARAM"],"mappings":"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"}
1
+ {"version":3,"file":"path.cjs","names":[],"sources":["../../src/path.ts"],"sourcesContent":["import { isServer } from '@tanstack/router-core/isServer'\nimport { last } from './utils'\nimport {\n SEGMENT_TYPE_OPTIONAL_PARAM,\n SEGMENT_TYPE_PARAM,\n SEGMENT_TYPE_PATHNAME,\n SEGMENT_TYPE_WILDCARD,\n parseSegment,\n} from './new-process-route-tree'\nimport type { LRUCache } from './lru-cache'\n\n/** Join path segments, cleaning duplicate slashes between parts. */\nexport function joinPaths(paths: Array<string | undefined>) {\n return cleanPath(\n paths\n .filter((val) => {\n return val !== undefined\n })\n .join('/'),\n )\n}\n\n/** Remove repeated slashes from a path string. */\nexport function cleanPath(path: string) {\n // remove double slashes\n return path.replace(/\\/{2,}/g, '/')\n}\n\n/** Trim leading slashes (except preserving root '/'). */\nexport function trimPathLeft(path: string) {\n return path === '/' ? path : path.replace(/^\\/{1,}/, '')\n}\n\n/** Trim trailing slashes (except preserving root '/'). */\nexport function trimPathRight(path: string) {\n const len = path.length\n return len > 1 && path[len - 1] === '/' ? path.replace(/\\/{1,}$/, '') : path\n}\n\n/** Trim both leading and trailing slashes. */\nexport function trimPath(path: string) {\n return trimPathRight(trimPathLeft(path))\n}\n\n/** Remove a trailing slash from value when appropriate for comparisons. */\nexport function removeTrailingSlash(value: string, basepath: string): string {\n if (value?.endsWith('/') && value !== '/' && value !== `${basepath}/`) {\n return value.slice(0, -1)\n }\n return value\n}\n\n// intended to only compare path name\n// see the usage in the isActive under useLinkProps\n// /sample/path1 = /sample/path1/\n// /sample/path1/some <> /sample/path1\n/**\n * Compare two pathnames for exact equality after normalizing trailing slashes\n * relative to the provided `basepath`.\n */\nexport function exactPathTest(\n pathName1: string,\n pathName2: string,\n basepath: string,\n): boolean {\n return (\n removeTrailingSlash(pathName1, basepath) ===\n removeTrailingSlash(pathName2, basepath)\n )\n}\n\n// When resolving relative paths, we treat all paths as if they are trailing slash\n// documents. All trailing slashes are removed after the path is resolved.\n// Here are a few examples:\n//\n// /a/b/c + ./d = /a/b/c/d\n// /a/b/c + ../d = /a/b/d\n// /a/b/c + ./d/ = /a/b/c/d\n// /a/b/c + ../d/ = /a/b/d\n// /a/b/c + ./ = /a/b/c\n//\n// Absolute paths that start with `/` short circuit the resolution process to the root\n// path.\n//\n// Here are some examples:\n//\n// /a/b/c + /d = /d\n// /a/b/c + /d/ = /d\n// /a/b/c + / = /\n//\n// Non-.-prefixed paths are still treated as relative paths, resolved like `./`\n//\n// Here are some examples:\n//\n// /a/b/c + d = /a/b/c/d\n// /a/b/c + d/ = /a/b/c/d\n// /a/b/c + d/e = /a/b/c/d/e\ninterface ResolvePathOptions {\n base: string\n to: string\n trailingSlash?: 'always' | 'never' | 'preserve'\n cache?: LRUCache<string, string>\n}\n\n/**\n * Resolve a destination path against a base, honoring trailing-slash policy\n * and supporting relative segments (`.`/`..`) and absolute `to` values.\n */\nexport function resolvePath({\n base,\n to,\n trailingSlash = 'never',\n cache,\n}: ResolvePathOptions) {\n const isAbsolute = to.startsWith('/')\n const isBase = !isAbsolute && to === '.'\n\n let key\n if (cache) {\n // `trailingSlash` is static per router, so it doesn't need to be part of the cache key\n key = isAbsolute ? to : isBase ? base : base + '\\0' + to\n const cached = cache.get(key)\n if (cached) return cached\n }\n\n let baseSegments: Array<string>\n if (isBase) {\n baseSegments = base.split('/')\n } else if (isAbsolute) {\n baseSegments = to.split('/')\n } else {\n baseSegments = base.split('/')\n while (baseSegments.length > 1 && last(baseSegments) === '') {\n baseSegments.pop()\n }\n\n const toSegments = to.split('/')\n for (let index = 0, length = toSegments.length; index < length; index++) {\n const value = toSegments[index]!\n if (value === '') {\n if (!index) {\n // Leading slash\n baseSegments = [value]\n } else if (index === length - 1) {\n // Trailing Slash\n baseSegments.push(value)\n } else {\n // ignore inter-slashes\n }\n } else if (value === '..') {\n baseSegments.pop()\n } else if (value === '.') {\n // ignore\n } else {\n baseSegments.push(value)\n }\n }\n }\n\n if (baseSegments.length > 1) {\n if (last(baseSegments) === '') {\n if (trailingSlash === 'never') {\n baseSegments.pop()\n }\n } else if (trailingSlash === 'always') {\n baseSegments.push('')\n }\n }\n\n let segment\n let joined = ''\n for (let i = 0; i < baseSegments.length; i++) {\n if (i > 0) joined += '/'\n const part = baseSegments[i]!\n if (!part) continue\n segment = parseSegment(part, 0, segment)\n const kind = segment[0]\n if (kind === SEGMENT_TYPE_PATHNAME) {\n joined += part\n continue\n }\n const end = segment[5]\n const prefix = part.substring(0, segment[1])\n const suffix = part.substring(segment[4], end)\n const value = part.substring(segment[2], segment[3])\n if (kind === SEGMENT_TYPE_PARAM) {\n joined += prefix || suffix ? `${prefix}{$${value}}${suffix}` : `$${value}`\n } else if (kind === SEGMENT_TYPE_WILDCARD) {\n joined += prefix || suffix ? `${prefix}{$}${suffix}` : '$'\n } else {\n // SEGMENT_TYPE_OPTIONAL_PARAM\n joined += `${prefix}{-$${value}}${suffix}`\n }\n }\n joined = cleanPath(joined)\n const result = joined || '/'\n if (key && cache) cache.set(key, result)\n return result\n}\n\n/**\n * Create a pre-compiled decode config from allowed characters.\n * This should be called once at router initialization.\n */\nexport function compileDecodeCharMap(\n pathParamsAllowedCharacters: ReadonlyArray<string>,\n) {\n const charMap = new Map(\n pathParamsAllowedCharacters.map((char) => [encodeURIComponent(char), char]),\n )\n // Escape special regex characters and join with |\n const pattern = Array.from(charMap.keys())\n .map((key) => key.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'))\n .join('|')\n const regex = new RegExp(pattern, 'g')\n return (encoded: string) =>\n encoded.replace(regex, (match) => charMap.get(match) ?? match)\n}\n\ninterface InterpolatePathOptions {\n path?: string\n params: Record<string, unknown>\n /**\n * A function that decodes a path parameter value.\n * Obtained from `compileDecodeCharMap(pathParamsAllowedCharacters)`.\n */\n decoder?: (encoded: string) => string\n /**\n * @internal\n * For testing only, in development mode we use the router.isServer value\n */\n server?: boolean\n}\n\ntype InterPolatePathResult = {\n interpolatedPath: string\n usedParams: Record<string, unknown>\n isMissingParams: boolean // true if any params were not available when being looked up in the params object\n}\n\nfunction encodeParam(\n key: string,\n params: InterpolatePathOptions['params'],\n decoder: InterpolatePathOptions['decoder'],\n): any {\n const value = params[key]\n if (typeof value !== 'string') return value\n\n if (key === '_splat') {\n // Early return if value only contains URL-safe characters (performance optimization)\n if (/^[a-zA-Z0-9\\-._~!/]*$/.test(value)) return value\n // the splat/catch-all routes shouldn't have the '/' encoded out\n // Use encodeURIComponent for each segment to properly encode spaces,\n // plus signs, and other special characters that encodeURI leaves unencoded\n return value\n .split('/')\n .map((segment) => encodePathParam(segment, decoder))\n .join('/')\n } else {\n return encodePathParam(value, decoder)\n }\n}\n\n/**\n * Interpolate params and wildcards into a route path template.\n *\n * - Encodes params safely (configurable allowed characters)\n * - Supports `{-$optional}` segments, `{prefix{$id}suffix}` and `{$}` wildcards\n */\nexport function interpolatePath({\n path,\n params,\n decoder,\n // `server` is marked @internal and stripped from .d.ts by `stripInternal`.\n // We avoid destructuring it in the function signature so the emitted\n // declaration doesn't reference a property that no longer exists.\n ...rest\n}: InterpolatePathOptions): InterPolatePathResult {\n // Tracking if any params are missing in the `params` object\n // when interpolating the path\n let isMissingParams = false\n const usedParams: Record<string, unknown> = Object.create(null)\n\n if (!path || path === '/')\n return { interpolatedPath: '/', usedParams, isMissingParams }\n if (!path.includes('$'))\n return { interpolatedPath: path, usedParams, isMissingParams }\n\n if (isServer ?? rest.server) {\n // Fast path for common templates like `/posts/$id` or `/files/$`.\n // Braced segments (`{...}`) are more complex (prefix/suffix/optional) and are\n // handled by the general parser below.\n if (path.indexOf('{') === -1) {\n const length = path.length\n let cursor = 0\n let joined = ''\n\n while (cursor < length) {\n // Skip slashes between segments. '/' code is 47\n while (cursor < length && path.charCodeAt(cursor) === 47) cursor++\n if (cursor >= length) break\n\n const start = cursor\n let end = path.indexOf('/', cursor)\n if (end === -1) end = length\n cursor = end\n\n const part = path.substring(start, end)\n if (!part) continue\n\n // `$id` or `$` (splat). '$' code is 36\n if (part.charCodeAt(0) === 36) {\n if (part.length === 1) {\n const splat = params._splat\n usedParams._splat = splat\n // TODO: Deprecate *\n usedParams['*'] = splat\n\n if (!splat) {\n isMissingParams = true\n continue\n }\n\n const value = encodeParam('_splat', params, decoder)\n joined += '/' + value\n } else {\n const key = part.substring(1)\n if (!isMissingParams && !(key in params)) {\n isMissingParams = true\n }\n usedParams[key] = params[key]\n\n const value = encodeParam(key, params, decoder) ?? 'undefined'\n joined += '/' + value\n }\n } else {\n joined += '/' + part\n }\n }\n\n if (path.endsWith('/')) joined += '/'\n\n const interpolatedPath = joined || '/'\n return { usedParams, interpolatedPath, isMissingParams }\n }\n }\n\n const length = path.length\n let cursor = 0\n let segment\n let joined = ''\n while (cursor < length) {\n const start = cursor\n segment = parseSegment(path, start, segment)\n const end = segment[5]\n cursor = end + 1\n\n if (start === end) continue\n\n const kind = segment[0]\n\n if (kind === SEGMENT_TYPE_PATHNAME) {\n joined += '/' + path.substring(start, end)\n continue\n }\n\n if (kind === SEGMENT_TYPE_WILDCARD) {\n const splat = params._splat\n usedParams._splat = splat\n // TODO: Deprecate *\n usedParams['*'] = splat\n\n const prefix = path.substring(start, segment[1])\n const suffix = path.substring(segment[4], end)\n\n // Check if _splat parameter is missing. _splat could be missing if undefined or an empty string or some other falsy value.\n if (!splat) {\n isMissingParams = true\n // For missing splat parameters, just return the prefix and suffix without the wildcard\n // If there is a prefix or suffix, return them joined, otherwise omit the segment\n if (prefix || suffix) {\n joined += '/' + prefix + suffix\n }\n continue\n }\n\n const value = encodeParam('_splat', params, decoder)\n joined += '/' + prefix + value + suffix\n continue\n }\n\n if (kind === SEGMENT_TYPE_PARAM) {\n const key = path.substring(segment[2], segment[3])\n if (!isMissingParams && !(key in params)) {\n isMissingParams = true\n }\n usedParams[key] = params[key]\n\n const prefix = path.substring(start, segment[1])\n const suffix = path.substring(segment[4], end)\n const value = encodeParam(key, params, decoder) ?? 'undefined'\n joined += '/' + prefix + value + suffix\n continue\n }\n\n if (kind === SEGMENT_TYPE_OPTIONAL_PARAM) {\n const key = path.substring(segment[2], segment[3])\n const valueRaw = params[key]\n\n // Check if optional parameter is missing or undefined\n if (valueRaw == null) continue\n\n usedParams[key] = valueRaw\n\n const prefix = path.substring(start, segment[1])\n const suffix = path.substring(segment[4], end)\n const value = encodeParam(key, params, decoder) ?? ''\n joined += '/' + prefix + value + suffix\n continue\n }\n }\n\n if (path.endsWith('/')) joined += '/'\n\n const interpolatedPath = joined || '/'\n\n return { usedParams, interpolatedPath, isMissingParams }\n}\n\nfunction encodePathParam(\n value: string,\n decoder?: InterpolatePathOptions['decoder'],\n) {\n const encoded = encodeURIComponent(value)\n return decoder?.(encoded) ?? encoded\n}\n"],"mappings":"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"}