@tanstack/router-core 1.121.19 → 1.121.21

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 (123) hide show
  1. package/dist/cjs/Matches.cjs +13 -0
  2. package/dist/cjs/Matches.cjs.map +1 -0
  3. package/dist/cjs/Matches.d.cts +109 -0
  4. package/dist/cjs/RouterProvider.d.cts +26 -0
  5. package/dist/cjs/defer.cjs +25 -0
  6. package/dist/cjs/defer.cjs.map +1 -0
  7. package/dist/cjs/defer.d.cts +20 -0
  8. package/dist/cjs/fileRoute.d.cts +23 -0
  9. package/dist/cjs/history.d.cts +8 -0
  10. package/dist/cjs/index.cjs +79 -0
  11. package/dist/cjs/index.cjs.map +1 -0
  12. package/dist/cjs/index.d.cts +41 -0
  13. package/dist/cjs/link.cjs +5 -0
  14. package/dist/cjs/link.cjs.map +1 -0
  15. package/dist/cjs/link.d.cts +212 -0
  16. package/dist/cjs/location.d.cts +12 -0
  17. package/dist/cjs/manifest.d.cts +24 -0
  18. package/dist/cjs/not-found.cjs +13 -0
  19. package/dist/cjs/not-found.cjs.map +1 -0
  20. package/dist/cjs/not-found.d.cts +20 -0
  21. package/dist/cjs/path.cjs +412 -0
  22. package/dist/cjs/path.cjs.map +1 -0
  23. package/dist/cjs/path.d.cts +56 -0
  24. package/dist/cjs/qss.cjs +36 -0
  25. package/dist/cjs/qss.cjs.map +1 -0
  26. package/dist/cjs/qss.d.cts +31 -0
  27. package/dist/cjs/redirect.cjs +42 -0
  28. package/dist/cjs/redirect.cjs.map +1 -0
  29. package/dist/cjs/redirect.d.cts +41 -0
  30. package/dist/cjs/root.cjs +5 -0
  31. package/dist/cjs/root.cjs.map +1 -0
  32. package/dist/cjs/root.d.cts +2 -0
  33. package/dist/cjs/route.cjs +119 -0
  34. package/dist/cjs/route.cjs.map +1 -0
  35. package/dist/cjs/route.d.cts +432 -0
  36. package/dist/cjs/routeInfo.d.cts +54 -0
  37. package/dist/cjs/router.cjs +1805 -0
  38. package/dist/cjs/router.cjs.map +1 -0
  39. package/dist/cjs/router.d.cts +627 -0
  40. package/dist/cjs/scroll-restoration.cjs +207 -0
  41. package/dist/cjs/scroll-restoration.cjs.map +1 -0
  42. package/dist/cjs/scroll-restoration.d.cts +38 -0
  43. package/dist/cjs/searchMiddleware.cjs +42 -0
  44. package/dist/cjs/searchMiddleware.cjs.map +1 -0
  45. package/dist/cjs/searchMiddleware.d.cts +5 -0
  46. package/dist/cjs/searchParams.cjs +61 -0
  47. package/dist/cjs/searchParams.cjs.map +1 -0
  48. package/dist/cjs/searchParams.d.cts +7 -0
  49. package/dist/cjs/serializer.d.cts +22 -0
  50. package/dist/cjs/structuralSharing.d.cts +4 -0
  51. package/dist/cjs/typePrimitives.d.cts +65 -0
  52. package/dist/cjs/useLoaderData.d.cts +5 -0
  53. package/dist/cjs/useLoaderDeps.d.cts +5 -0
  54. package/dist/cjs/useNavigate.d.cts +3 -0
  55. package/dist/cjs/useParams.d.cts +5 -0
  56. package/dist/cjs/useRouteContext.d.cts +9 -0
  57. package/dist/cjs/useSearch.d.cts +5 -0
  58. package/dist/cjs/utils.cjs +165 -0
  59. package/dist/cjs/utils.cjs.map +1 -0
  60. package/dist/cjs/utils.d.cts +94 -0
  61. package/dist/cjs/validators.d.cts +51 -0
  62. package/dist/esm/Matches.d.ts +109 -0
  63. package/dist/esm/Matches.js +13 -0
  64. package/dist/esm/Matches.js.map +1 -0
  65. package/dist/esm/RouterProvider.d.ts +26 -0
  66. package/dist/esm/defer.d.ts +20 -0
  67. package/dist/esm/defer.js +25 -0
  68. package/dist/esm/defer.js.map +1 -0
  69. package/dist/esm/fileRoute.d.ts +23 -0
  70. package/dist/esm/history.d.ts +8 -0
  71. package/dist/esm/index.d.ts +41 -0
  72. package/dist/esm/index.js +79 -0
  73. package/dist/esm/index.js.map +1 -0
  74. package/dist/esm/link.d.ts +212 -0
  75. package/dist/esm/link.js +5 -0
  76. package/dist/esm/link.js.map +1 -0
  77. package/dist/esm/location.d.ts +12 -0
  78. package/dist/esm/manifest.d.ts +24 -0
  79. package/dist/esm/not-found.d.ts +20 -0
  80. package/dist/esm/not-found.js +13 -0
  81. package/dist/esm/not-found.js.map +1 -0
  82. package/dist/esm/path.d.ts +56 -0
  83. package/dist/esm/path.js +412 -0
  84. package/dist/esm/path.js.map +1 -0
  85. package/dist/esm/qss.d.ts +31 -0
  86. package/dist/esm/qss.js +36 -0
  87. package/dist/esm/qss.js.map +1 -0
  88. package/dist/esm/redirect.d.ts +41 -0
  89. package/dist/esm/redirect.js +42 -0
  90. package/dist/esm/redirect.js.map +1 -0
  91. package/dist/esm/root.d.ts +2 -0
  92. package/dist/esm/root.js +5 -0
  93. package/dist/esm/root.js.map +1 -0
  94. package/dist/esm/route.d.ts +432 -0
  95. package/dist/esm/route.js +119 -0
  96. package/dist/esm/route.js.map +1 -0
  97. package/dist/esm/routeInfo.d.ts +54 -0
  98. package/dist/esm/router.d.ts +627 -0
  99. package/dist/esm/router.js +1805 -0
  100. package/dist/esm/router.js.map +1 -0
  101. package/dist/esm/scroll-restoration.d.ts +38 -0
  102. package/dist/esm/scroll-restoration.js +207 -0
  103. package/dist/esm/scroll-restoration.js.map +1 -0
  104. package/dist/esm/searchMiddleware.d.ts +5 -0
  105. package/dist/esm/searchMiddleware.js +42 -0
  106. package/dist/esm/searchMiddleware.js.map +1 -0
  107. package/dist/esm/searchParams.d.ts +7 -0
  108. package/dist/esm/searchParams.js +61 -0
  109. package/dist/esm/searchParams.js.map +1 -0
  110. package/dist/esm/serializer.d.ts +22 -0
  111. package/dist/esm/structuralSharing.d.ts +4 -0
  112. package/dist/esm/typePrimitives.d.ts +65 -0
  113. package/dist/esm/useLoaderData.d.ts +5 -0
  114. package/dist/esm/useLoaderDeps.d.ts +5 -0
  115. package/dist/esm/useNavigate.d.ts +3 -0
  116. package/dist/esm/useParams.d.ts +5 -0
  117. package/dist/esm/useRouteContext.d.ts +9 -0
  118. package/dist/esm/useSearch.d.ts +5 -0
  119. package/dist/esm/utils.d.ts +94 -0
  120. package/dist/esm/utils.js +165 -0
  121. package/dist/esm/utils.js.map +1 -0
  122. package/dist/esm/validators.d.ts +51 -0
  123. package/package.json +2 -2
@@ -0,0 +1,412 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const utils = require("./utils.cjs");
4
+ function joinPaths(paths) {
5
+ return cleanPath(
6
+ paths.filter((val) => {
7
+ return val !== void 0;
8
+ }).join("/")
9
+ );
10
+ }
11
+ function cleanPath(path) {
12
+ return path.replace(/\/{2,}/g, "/");
13
+ }
14
+ function trimPathLeft(path) {
15
+ return path === "/" ? path : path.replace(/^\/{1,}/, "");
16
+ }
17
+ function trimPathRight(path) {
18
+ return path === "/" ? path : path.replace(/\/{1,}$/, "");
19
+ }
20
+ function trimPath(path) {
21
+ return trimPathRight(trimPathLeft(path));
22
+ }
23
+ function removeTrailingSlash(value, basepath) {
24
+ if ((value == null ? void 0 : value.endsWith("/")) && value !== "/" && value !== `${basepath}/`) {
25
+ return value.slice(0, -1);
26
+ }
27
+ return value;
28
+ }
29
+ function exactPathTest(pathName1, pathName2, basepath) {
30
+ return removeTrailingSlash(pathName1, basepath) === removeTrailingSlash(pathName2, basepath);
31
+ }
32
+ function resolvePath({
33
+ basepath,
34
+ base,
35
+ to,
36
+ trailingSlash = "never",
37
+ caseSensitive
38
+ }) {
39
+ var _a, _b;
40
+ base = removeBasepath(basepath, base, caseSensitive);
41
+ to = removeBasepath(basepath, to, caseSensitive);
42
+ let baseSegments = parsePathname(base);
43
+ const toSegments = parsePathname(to);
44
+ if (baseSegments.length > 1 && ((_a = utils.last(baseSegments)) == null ? void 0 : _a.value) === "/") {
45
+ baseSegments.pop();
46
+ }
47
+ toSegments.forEach((toSegment, index) => {
48
+ if (toSegment.value === "/") {
49
+ if (!index) {
50
+ baseSegments = [toSegment];
51
+ } else if (index === toSegments.length - 1) {
52
+ baseSegments.push(toSegment);
53
+ } else ;
54
+ } else if (toSegment.value === "..") {
55
+ baseSegments.pop();
56
+ } else if (toSegment.value === ".") ;
57
+ else {
58
+ baseSegments.push(toSegment);
59
+ }
60
+ });
61
+ if (baseSegments.length > 1) {
62
+ if (((_b = utils.last(baseSegments)) == null ? void 0 : _b.value) === "/") {
63
+ if (trailingSlash === "never") {
64
+ baseSegments.pop();
65
+ }
66
+ } else if (trailingSlash === "always") {
67
+ baseSegments.push({ type: "pathname", value: "/" });
68
+ }
69
+ }
70
+ const segmentValues = baseSegments.map((segment) => {
71
+ if (segment.type === "param") {
72
+ const param = segment.value.substring(1);
73
+ if (segment.prefixSegment && segment.suffixSegment) {
74
+ return `${segment.prefixSegment}{$${param}}${segment.suffixSegment}`;
75
+ } else if (segment.prefixSegment) {
76
+ return `${segment.prefixSegment}{$${param}}`;
77
+ } else if (segment.suffixSegment) {
78
+ return `{$${param}}${segment.suffixSegment}`;
79
+ }
80
+ }
81
+ if (segment.type === "wildcard") {
82
+ if (segment.prefixSegment && segment.suffixSegment) {
83
+ return `${segment.prefixSegment}{$}${segment.suffixSegment}`;
84
+ } else if (segment.prefixSegment) {
85
+ return `${segment.prefixSegment}{$}`;
86
+ } else if (segment.suffixSegment) {
87
+ return `{$}${segment.suffixSegment}`;
88
+ }
89
+ }
90
+ return segment.value;
91
+ });
92
+ const joined = joinPaths([basepath, ...segmentValues]);
93
+ return cleanPath(joined);
94
+ }
95
+ const PARAM_RE = /^\$.{1,}$/;
96
+ const PARAM_W_CURLY_BRACES_RE = /^(.*?)\{(\$[a-zA-Z_$][a-zA-Z0-9_$]*)\}(.*)$/;
97
+ const WILDCARD_RE = /^\$$/;
98
+ const WILDCARD_W_CURLY_BRACES_RE = /^(.*?)\{\$\}(.*)$/;
99
+ function parsePathname(pathname) {
100
+ if (!pathname) {
101
+ return [];
102
+ }
103
+ pathname = cleanPath(pathname);
104
+ const segments = [];
105
+ if (pathname.slice(0, 1) === "/") {
106
+ pathname = pathname.substring(1);
107
+ segments.push({
108
+ type: "pathname",
109
+ value: "/"
110
+ });
111
+ }
112
+ if (!pathname) {
113
+ return segments;
114
+ }
115
+ const split = pathname.split("/").filter(Boolean);
116
+ segments.push(
117
+ ...split.map((part) => {
118
+ const wildcardBracesMatch = part.match(WILDCARD_W_CURLY_BRACES_RE);
119
+ if (wildcardBracesMatch) {
120
+ const prefix = wildcardBracesMatch[1];
121
+ const suffix = wildcardBracesMatch[2];
122
+ return {
123
+ type: "wildcard",
124
+ value: "$",
125
+ prefixSegment: prefix || void 0,
126
+ suffixSegment: suffix || void 0
127
+ };
128
+ }
129
+ const paramBracesMatch = part.match(PARAM_W_CURLY_BRACES_RE);
130
+ if (paramBracesMatch) {
131
+ const prefix = paramBracesMatch[1];
132
+ const paramName = paramBracesMatch[2];
133
+ const suffix = paramBracesMatch[3];
134
+ return {
135
+ type: "param",
136
+ value: "" + paramName,
137
+ prefixSegment: prefix || void 0,
138
+ suffixSegment: suffix || void 0
139
+ };
140
+ }
141
+ if (PARAM_RE.test(part)) {
142
+ const paramName = part.substring(1);
143
+ return {
144
+ type: "param",
145
+ value: "$" + paramName,
146
+ prefixSegment: void 0,
147
+ suffixSegment: void 0
148
+ };
149
+ }
150
+ if (WILDCARD_RE.test(part)) {
151
+ return {
152
+ type: "wildcard",
153
+ value: "$",
154
+ prefixSegment: void 0,
155
+ suffixSegment: void 0
156
+ };
157
+ }
158
+ return {
159
+ type: "pathname",
160
+ value: part.includes("%25") ? part.split("%25").map((segment) => decodeURI(segment)).join("%25") : decodeURI(part)
161
+ };
162
+ })
163
+ );
164
+ if (pathname.slice(-1) === "/") {
165
+ pathname = pathname.substring(1);
166
+ segments.push({
167
+ type: "pathname",
168
+ value: "/"
169
+ });
170
+ }
171
+ return segments;
172
+ }
173
+ function interpolatePath({
174
+ path,
175
+ params,
176
+ leaveWildcards,
177
+ leaveParams,
178
+ decodeCharMap
179
+ }) {
180
+ const interpolatedPathSegments = parsePathname(path);
181
+ function encodeParam(key) {
182
+ const value = params[key];
183
+ const isValueString = typeof value === "string";
184
+ if (["*", "_splat"].includes(key)) {
185
+ return isValueString ? encodeURI(value) : value;
186
+ } else {
187
+ return isValueString ? encodePathParam(value, decodeCharMap) : value;
188
+ }
189
+ }
190
+ let isMissingParams = false;
191
+ const usedParams = {};
192
+ const interpolatedPath = joinPaths(
193
+ interpolatedPathSegments.map((segment) => {
194
+ if (segment.type === "wildcard") {
195
+ usedParams._splat = params._splat;
196
+ const segmentPrefix = segment.prefixSegment || "";
197
+ const segmentSuffix = segment.suffixSegment || "";
198
+ const value = encodeParam("_splat");
199
+ if (leaveWildcards) {
200
+ return `${segmentPrefix}${segment.value}${value ?? ""}${segmentSuffix}`;
201
+ }
202
+ return `${segmentPrefix}${value}${segmentSuffix}`;
203
+ }
204
+ if (segment.type === "param") {
205
+ const key = segment.value.substring(1);
206
+ if (!isMissingParams && !(key in params)) {
207
+ isMissingParams = true;
208
+ }
209
+ usedParams[key] = params[key];
210
+ const segmentPrefix = segment.prefixSegment || "";
211
+ const segmentSuffix = segment.suffixSegment || "";
212
+ if (leaveParams) {
213
+ const value = encodeParam(segment.value);
214
+ return `${segmentPrefix}${segment.value}${value ?? ""}${segmentSuffix}`;
215
+ }
216
+ return `${segmentPrefix}${encodeParam(key) ?? "undefined"}${segmentSuffix}`;
217
+ }
218
+ return segment.value;
219
+ })
220
+ );
221
+ return { usedParams, interpolatedPath, isMissingParams };
222
+ }
223
+ function encodePathParam(value, decodeCharMap) {
224
+ let encoded = encodeURIComponent(value);
225
+ if (decodeCharMap) {
226
+ for (const [encodedChar, char] of decodeCharMap) {
227
+ encoded = encoded.replaceAll(encodedChar, char);
228
+ }
229
+ }
230
+ return encoded;
231
+ }
232
+ function matchPathname(basepath, currentPathname, matchLocation) {
233
+ const pathParams = matchByPath(basepath, currentPathname, matchLocation);
234
+ if (matchLocation.to && !pathParams) {
235
+ return;
236
+ }
237
+ return pathParams ?? {};
238
+ }
239
+ function removeBasepath(basepath, pathname, caseSensitive = false) {
240
+ const normalizedBasepath = caseSensitive ? basepath : basepath.toLowerCase();
241
+ const normalizedPathname = caseSensitive ? pathname : pathname.toLowerCase();
242
+ switch (true) {
243
+ // default behaviour is to serve app from the root - pathname
244
+ // left untouched
245
+ case normalizedBasepath === "/":
246
+ return pathname;
247
+ // shortcut for removing the basepath if it matches the pathname
248
+ case normalizedPathname === normalizedBasepath:
249
+ return "";
250
+ // in case pathname is shorter than basepath - there is
251
+ // nothing to remove
252
+ case pathname.length < basepath.length:
253
+ return pathname;
254
+ // avoid matching partial segments - strict equality handled
255
+ // earlier, otherwise, basepath separated from pathname with
256
+ // separator, therefore lack of separator means partial
257
+ // segment match (`/app` should not match `/application`)
258
+ case normalizedPathname[normalizedBasepath.length] !== "/":
259
+ return pathname;
260
+ // remove the basepath from the pathname if it starts with it
261
+ case normalizedPathname.startsWith(normalizedBasepath):
262
+ return pathname.slice(basepath.length);
263
+ // otherwise, return the pathname as is
264
+ default:
265
+ return pathname;
266
+ }
267
+ }
268
+ function matchByPath(basepath, from, matchLocation) {
269
+ if (basepath !== "/" && !from.startsWith(basepath)) {
270
+ return void 0;
271
+ }
272
+ from = removeBasepath(basepath, from, matchLocation.caseSensitive);
273
+ const to = removeBasepath(
274
+ basepath,
275
+ `${matchLocation.to ?? "$"}`,
276
+ matchLocation.caseSensitive
277
+ );
278
+ const baseSegments = parsePathname(from);
279
+ const routeSegments = parsePathname(to);
280
+ if (!from.startsWith("/")) {
281
+ baseSegments.unshift({
282
+ type: "pathname",
283
+ value: "/"
284
+ });
285
+ }
286
+ if (!to.startsWith("/")) {
287
+ routeSegments.unshift({
288
+ type: "pathname",
289
+ value: "/"
290
+ });
291
+ }
292
+ const params = {};
293
+ const isMatch = (() => {
294
+ var _a;
295
+ for (let i = 0; i < Math.max(baseSegments.length, routeSegments.length); i++) {
296
+ const baseSegment = baseSegments[i];
297
+ const routeSegment = routeSegments[i];
298
+ const isLastBaseSegment = i >= baseSegments.length - 1;
299
+ const isLastRouteSegment = i >= routeSegments.length - 1;
300
+ if (routeSegment) {
301
+ if (routeSegment.type === "wildcard") {
302
+ const remainingBaseSegments = baseSegments.slice(i);
303
+ let _splat;
304
+ if (routeSegment.prefixSegment || routeSegment.suffixSegment) {
305
+ if (!baseSegment) return false;
306
+ const prefix = routeSegment.prefixSegment || "";
307
+ const suffix = routeSegment.suffixSegment || "";
308
+ const baseValue = baseSegment.value;
309
+ if ("prefixSegment" in routeSegment) {
310
+ if (!baseValue.startsWith(prefix)) {
311
+ return false;
312
+ }
313
+ }
314
+ if ("suffixSegment" in routeSegment) {
315
+ if (!((_a = baseSegments[baseSegments.length - 1]) == null ? void 0 : _a.value.endsWith(suffix))) {
316
+ return false;
317
+ }
318
+ }
319
+ let rejoinedSplat = decodeURI(
320
+ joinPaths(remainingBaseSegments.map((d) => d.value))
321
+ );
322
+ if (prefix && rejoinedSplat.startsWith(prefix)) {
323
+ rejoinedSplat = rejoinedSplat.slice(prefix.length);
324
+ }
325
+ if (suffix && rejoinedSplat.endsWith(suffix)) {
326
+ rejoinedSplat = rejoinedSplat.slice(
327
+ 0,
328
+ rejoinedSplat.length - suffix.length
329
+ );
330
+ }
331
+ _splat = rejoinedSplat;
332
+ } else {
333
+ _splat = decodeURI(
334
+ joinPaths(remainingBaseSegments.map((d) => d.value))
335
+ );
336
+ }
337
+ params["*"] = _splat;
338
+ params["_splat"] = _splat;
339
+ return true;
340
+ }
341
+ if (routeSegment.type === "pathname") {
342
+ if (routeSegment.value === "/" && !(baseSegment == null ? void 0 : baseSegment.value)) {
343
+ return true;
344
+ }
345
+ if (baseSegment) {
346
+ if (matchLocation.caseSensitive) {
347
+ if (routeSegment.value !== baseSegment.value) {
348
+ return false;
349
+ }
350
+ } else if (routeSegment.value.toLowerCase() !== baseSegment.value.toLowerCase()) {
351
+ return false;
352
+ }
353
+ }
354
+ }
355
+ if (!baseSegment) {
356
+ return false;
357
+ }
358
+ if (routeSegment.type === "param") {
359
+ if (baseSegment.value === "/") {
360
+ return false;
361
+ }
362
+ let _paramValue;
363
+ if (routeSegment.prefixSegment || routeSegment.suffixSegment) {
364
+ const prefix = routeSegment.prefixSegment || "";
365
+ const suffix = routeSegment.suffixSegment || "";
366
+ const baseValue = baseSegment.value;
367
+ if (prefix && !baseValue.startsWith(prefix)) {
368
+ return false;
369
+ }
370
+ if (suffix && !baseValue.endsWith(suffix)) {
371
+ return false;
372
+ }
373
+ let paramValue = baseValue;
374
+ if (prefix && paramValue.startsWith(prefix)) {
375
+ paramValue = paramValue.slice(prefix.length);
376
+ }
377
+ if (suffix && paramValue.endsWith(suffix)) {
378
+ paramValue = paramValue.slice(
379
+ 0,
380
+ paramValue.length - suffix.length
381
+ );
382
+ }
383
+ _paramValue = decodeURIComponent(paramValue);
384
+ } else {
385
+ _paramValue = decodeURIComponent(baseSegment.value);
386
+ }
387
+ params[routeSegment.value.substring(1)] = _paramValue;
388
+ }
389
+ }
390
+ if (!isLastBaseSegment && isLastRouteSegment) {
391
+ params["**"] = joinPaths(baseSegments.slice(i + 1).map((d) => d.value));
392
+ return !!matchLocation.fuzzy && (routeSegment == null ? void 0 : routeSegment.value) !== "/";
393
+ }
394
+ }
395
+ return true;
396
+ })();
397
+ return isMatch ? params : void 0;
398
+ }
399
+ exports.cleanPath = cleanPath;
400
+ exports.exactPathTest = exactPathTest;
401
+ exports.interpolatePath = interpolatePath;
402
+ exports.joinPaths = joinPaths;
403
+ exports.matchByPath = matchByPath;
404
+ exports.matchPathname = matchPathname;
405
+ exports.parsePathname = parsePathname;
406
+ exports.removeBasepath = removeBasepath;
407
+ exports.removeTrailingSlash = removeTrailingSlash;
408
+ exports.resolvePath = resolvePath;
409
+ exports.trimPath = trimPath;
410
+ exports.trimPathLeft = trimPathLeft;
411
+ exports.trimPathRight = trimPathRight;
412
+ //# sourceMappingURL=path.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path.cjs","sources":["../../src/path.ts"],"sourcesContent":["import { last } from './utils'\nimport type { MatchLocation } from './RouterProvider'\nimport type { AnyPathParams } from './route'\n\nexport interface Segment {\n type: 'pathname' | 'param' | 'wildcard'\n value: string\n // Add a new property to store the static segment if present\n prefixSegment?: string\n suffixSegment?: string\n}\n\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\nexport function cleanPath(path: string) {\n // remove double slashes\n return path.replace(/\\/{2,}/g, '/')\n}\n\nexport function trimPathLeft(path: string) {\n return path === '/' ? path : path.replace(/^\\/{1,}/, '')\n}\n\nexport function trimPathRight(path: string) {\n return path === '/' ? path : path.replace(/\\/{1,}$/, '')\n}\n\nexport function trimPath(path: string) {\n return trimPathRight(trimPathLeft(path))\n}\n\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\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 basepath: string\n base: string\n to: string\n trailingSlash?: 'always' | 'never' | 'preserve'\n caseSensitive?: boolean\n}\n\nexport function resolvePath({\n basepath,\n base,\n to,\n trailingSlash = 'never',\n caseSensitive,\n}: ResolvePathOptions) {\n base = removeBasepath(basepath, base, caseSensitive)\n to = removeBasepath(basepath, to, caseSensitive)\n\n let baseSegments = parsePathname(base)\n const toSegments = parsePathname(to)\n\n if (baseSegments.length > 1 && last(baseSegments)?.value === '/') {\n baseSegments.pop()\n }\n\n toSegments.forEach((toSegment, index) => {\n if (toSegment.value === '/') {\n if (!index) {\n // Leading slash\n baseSegments = [toSegment]\n } else if (index === toSegments.length - 1) {\n // Trailing Slash\n baseSegments.push(toSegment)\n } else {\n // ignore inter-slashes\n }\n } else if (toSegment.value === '..') {\n baseSegments.pop()\n } else if (toSegment.value === '.') {\n // ignore\n } else {\n baseSegments.push(toSegment)\n }\n })\n\n if (baseSegments.length > 1) {\n if (last(baseSegments)?.value === '/') {\n if (trailingSlash === 'never') {\n baseSegments.pop()\n }\n } else if (trailingSlash === 'always') {\n baseSegments.push({ type: 'pathname', value: '/' })\n }\n }\n\n const segmentValues = baseSegments.map((segment) => {\n if (segment.type === 'param') {\n const param = segment.value.substring(1)\n if (segment.prefixSegment && segment.suffixSegment) {\n return `${segment.prefixSegment}{$${param}}${segment.suffixSegment}`\n } else if (segment.prefixSegment) {\n return `${segment.prefixSegment}{$${param}}`\n } else if (segment.suffixSegment) {\n return `{$${param}}${segment.suffixSegment}`\n }\n }\n if (segment.type === 'wildcard') {\n if (segment.prefixSegment && segment.suffixSegment) {\n return `${segment.prefixSegment}{$}${segment.suffixSegment}`\n } else if (segment.prefixSegment) {\n return `${segment.prefixSegment}{$}`\n } else if (segment.suffixSegment) {\n return `{$}${segment.suffixSegment}`\n }\n }\n return segment.value\n })\n const joined = joinPaths([basepath, ...segmentValues])\n return cleanPath(joined)\n}\n\nconst PARAM_RE = /^\\$.{1,}$/ // $paramName\nconst PARAM_W_CURLY_BRACES_RE = /^(.*?)\\{(\\$[a-zA-Z_$][a-zA-Z0-9_$]*)\\}(.*)$/ // prefix{$paramName}suffix\nconst WILDCARD_RE = /^\\$$/ // $\nconst WILDCARD_W_CURLY_BRACES_RE = /^(.*?)\\{\\$\\}(.*)$/ // prefix{$}suffix\n\n/**\n * Required: `/foo/$bar` ✅\n * Prefix and Suffix: `/foo/prefix${bar}suffix` ✅\n * Wildcard: `/foo/$` ✅\n * Wildcard with Prefix and Suffix: `/foo/prefix{$}suffix` ✅\n *\n * Future:\n * Optional: `/foo/{-bar}`\n * Optional named segment: `/foo/{bar}`\n * Optional named segment with Prefix and Suffix: `/foo/prefix{-bar}suffix`\n * Escape special characters:\n * - `/foo/[$]` - Static route\n * - `/foo/[$]{$foo} - Dynamic route with a static prefix of `$`\n * - `/foo/{$foo}[$]` - Dynamic route with a static suffix of `$`\n */\nexport function parsePathname(pathname?: string): Array<Segment> {\n if (!pathname) {\n return []\n }\n\n pathname = cleanPath(pathname)\n\n const segments: Array<Segment> = []\n\n if (pathname.slice(0, 1) === '/') {\n pathname = pathname.substring(1)\n segments.push({\n type: 'pathname',\n value: '/',\n })\n }\n\n if (!pathname) {\n return segments\n }\n\n // Remove empty segments and '.' segments\n const split = pathname.split('/').filter(Boolean)\n\n segments.push(\n ...split.map((part): Segment => {\n // Check for wildcard with curly braces: prefix{$}suffix\n const wildcardBracesMatch = part.match(WILDCARD_W_CURLY_BRACES_RE)\n if (wildcardBracesMatch) {\n const prefix = wildcardBracesMatch[1]\n const suffix = wildcardBracesMatch[2]\n return {\n type: 'wildcard',\n value: '$',\n prefixSegment: prefix || undefined,\n suffixSegment: suffix || undefined,\n }\n }\n\n // Check for the new parameter format: prefix{$paramName}suffix\n const paramBracesMatch = part.match(PARAM_W_CURLY_BRACES_RE)\n if (paramBracesMatch) {\n const prefix = paramBracesMatch[1]\n const paramName = paramBracesMatch[2]\n const suffix = paramBracesMatch[3]\n return {\n type: 'param',\n value: '' + paramName,\n prefixSegment: prefix || undefined,\n suffixSegment: suffix || undefined,\n }\n }\n\n // Check for bare parameter format: $paramName (without curly braces)\n if (PARAM_RE.test(part)) {\n const paramName = part.substring(1)\n return {\n type: 'param',\n value: '$' + paramName,\n prefixSegment: undefined,\n suffixSegment: undefined,\n }\n }\n\n // Check for bare wildcard: $ (without curly braces)\n if (WILDCARD_RE.test(part)) {\n return {\n type: 'wildcard',\n value: '$',\n prefixSegment: undefined,\n suffixSegment: undefined,\n }\n }\n\n // Handle regular pathname segment\n return {\n type: 'pathname',\n value: part.includes('%25')\n ? part\n .split('%25')\n .map((segment) => decodeURI(segment))\n .join('%25')\n : decodeURI(part),\n }\n }),\n )\n\n if (pathname.slice(-1) === '/') {\n pathname = pathname.substring(1)\n segments.push({\n type: 'pathname',\n value: '/',\n })\n }\n\n return segments\n}\n\ninterface InterpolatePathOptions {\n path?: string\n params: Record<string, unknown>\n leaveWildcards?: boolean\n leaveParams?: boolean\n // Map of encoded chars to decoded chars (e.g. '%40' -> '@') that should remain decoded in path params\n decodeCharMap?: Map<string, string>\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}\nexport function interpolatePath({\n path,\n params,\n leaveWildcards,\n leaveParams,\n decodeCharMap,\n}: InterpolatePathOptions): InterPolatePathResult {\n const interpolatedPathSegments = parsePathname(path)\n\n function encodeParam(key: string): any {\n const value = params[key]\n const isValueString = typeof value === 'string'\n\n if (['*', '_splat'].includes(key)) {\n // the splat/catch-all routes shouldn't have the '/' encoded out\n return isValueString ? encodeURI(value) : value\n } else {\n return isValueString ? encodePathParam(value, decodeCharMap) : value\n }\n }\n\n // Tracking if any params are missing in the `params` object\n // when interpolating the path\n let isMissingParams = false\n\n const usedParams: Record<string, unknown> = {}\n const interpolatedPath = joinPaths(\n interpolatedPathSegments.map((segment) => {\n if (segment.type === 'wildcard') {\n usedParams._splat = params._splat\n const segmentPrefix = segment.prefixSegment || ''\n const segmentSuffix = segment.suffixSegment || ''\n const value = encodeParam('_splat')\n if (leaveWildcards) {\n return `${segmentPrefix}${segment.value}${value ?? ''}${segmentSuffix}`\n }\n return `${segmentPrefix}${value}${segmentSuffix}`\n }\n\n if (segment.type === 'param') {\n const key = segment.value.substring(1)\n if (!isMissingParams && !(key in params)) {\n isMissingParams = true\n }\n usedParams[key] = params[key]\n\n const segmentPrefix = segment.prefixSegment || ''\n const segmentSuffix = segment.suffixSegment || ''\n if (leaveParams) {\n const value = encodeParam(segment.value)\n return `${segmentPrefix}${segment.value}${value ?? ''}${segmentSuffix}`\n }\n return `${segmentPrefix}${encodeParam(key) ?? 'undefined'}${segmentSuffix}`\n }\n\n return segment.value\n }),\n )\n return { usedParams, interpolatedPath, isMissingParams }\n}\n\nfunction encodePathParam(value: string, decodeCharMap?: Map<string, string>) {\n let encoded = encodeURIComponent(value)\n if (decodeCharMap) {\n for (const [encodedChar, char] of decodeCharMap) {\n encoded = encoded.replaceAll(encodedChar, char)\n }\n }\n return encoded\n}\n\nexport function matchPathname(\n basepath: string,\n currentPathname: string,\n matchLocation: Pick<MatchLocation, 'to' | 'fuzzy' | 'caseSensitive'>,\n): AnyPathParams | undefined {\n const pathParams = matchByPath(basepath, currentPathname, matchLocation)\n // const searchMatched = matchBySearch(location.search, matchLocation)\n\n if (matchLocation.to && !pathParams) {\n return\n }\n\n return pathParams ?? {}\n}\n\nexport function removeBasepath(\n basepath: string,\n pathname: string,\n caseSensitive: boolean = false,\n) {\n // normalize basepath and pathname for case-insensitive comparison if needed\n const normalizedBasepath = caseSensitive ? basepath : basepath.toLowerCase()\n const normalizedPathname = caseSensitive ? pathname : pathname.toLowerCase()\n\n switch (true) {\n // default behaviour is to serve app from the root - pathname\n // left untouched\n case normalizedBasepath === '/':\n return pathname\n\n // shortcut for removing the basepath if it matches the pathname\n case normalizedPathname === normalizedBasepath:\n return ''\n\n // in case pathname is shorter than basepath - there is\n // nothing to remove\n case pathname.length < basepath.length:\n return pathname\n\n // avoid matching partial segments - strict equality handled\n // earlier, otherwise, basepath separated from pathname with\n // separator, therefore lack of separator means partial\n // segment match (`/app` should not match `/application`)\n case normalizedPathname[normalizedBasepath.length] !== '/':\n return pathname\n\n // remove the basepath from the pathname if it starts with it\n case normalizedPathname.startsWith(normalizedBasepath):\n return pathname.slice(basepath.length)\n\n // otherwise, return the pathname as is\n default:\n return pathname\n }\n}\n\nexport function matchByPath(\n basepath: string,\n from: string,\n matchLocation: Pick<MatchLocation, 'to' | 'caseSensitive' | 'fuzzy'>,\n): Record<string, string> | undefined {\n // check basepath first\n if (basepath !== '/' && !from.startsWith(basepath)) {\n return undefined\n }\n // Remove the base path from the pathname\n from = removeBasepath(basepath, from, matchLocation.caseSensitive)\n // Default to to $ (wildcard)\n const to = removeBasepath(\n basepath,\n `${matchLocation.to ?? '$'}`,\n matchLocation.caseSensitive,\n )\n\n // Parse the from and to\n const baseSegments = parsePathname(from)\n const routeSegments = parsePathname(to)\n\n if (!from.startsWith('/')) {\n baseSegments.unshift({\n type: 'pathname',\n value: '/',\n })\n }\n\n if (!to.startsWith('/')) {\n routeSegments.unshift({\n type: 'pathname',\n value: '/',\n })\n }\n\n const params: Record<string, string> = {}\n\n const isMatch = (() => {\n for (\n let i = 0;\n i < Math.max(baseSegments.length, routeSegments.length);\n i++\n ) {\n const baseSegment = baseSegments[i]\n const routeSegment = routeSegments[i]\n\n const isLastBaseSegment = i >= baseSegments.length - 1\n const isLastRouteSegment = i >= routeSegments.length - 1\n\n if (routeSegment) {\n if (routeSegment.type === 'wildcard') {\n // Capture all remaining segments for a wildcard\n const remainingBaseSegments = baseSegments.slice(i)\n\n let _splat: string\n\n // If this is a wildcard with prefix/suffix, we need to handle the first segment specially\n if (routeSegment.prefixSegment || routeSegment.suffixSegment) {\n if (!baseSegment) return false\n\n const prefix = routeSegment.prefixSegment || ''\n const suffix = routeSegment.suffixSegment || ''\n\n // Check if the base segment starts with prefix and ends with suffix\n const baseValue = baseSegment.value\n if ('prefixSegment' in routeSegment) {\n if (!baseValue.startsWith(prefix)) {\n return false\n }\n }\n if ('suffixSegment' in routeSegment) {\n if (\n !baseSegments[baseSegments.length - 1]?.value.endsWith(suffix)\n ) {\n return false\n }\n }\n\n let rejoinedSplat = decodeURI(\n joinPaths(remainingBaseSegments.map((d) => d.value)),\n )\n\n // Remove the prefix and suffix from the rejoined splat\n if (prefix && rejoinedSplat.startsWith(prefix)) {\n rejoinedSplat = rejoinedSplat.slice(prefix.length)\n }\n\n if (suffix && rejoinedSplat.endsWith(suffix)) {\n rejoinedSplat = rejoinedSplat.slice(\n 0,\n rejoinedSplat.length - suffix.length,\n )\n }\n\n _splat = rejoinedSplat\n } else {\n // If no prefix/suffix, just rejoin the remaining segments\n _splat = decodeURI(\n joinPaths(remainingBaseSegments.map((d) => d.value)),\n )\n }\n\n // TODO: Deprecate *\n params['*'] = _splat\n params['_splat'] = _splat\n return true\n }\n\n if (routeSegment.type === 'pathname') {\n if (routeSegment.value === '/' && !baseSegment?.value) {\n return true\n }\n\n if (baseSegment) {\n if (matchLocation.caseSensitive) {\n if (routeSegment.value !== baseSegment.value) {\n return false\n }\n } else if (\n routeSegment.value.toLowerCase() !==\n baseSegment.value.toLowerCase()\n ) {\n return false\n }\n }\n }\n\n if (!baseSegment) {\n return false\n }\n\n if (routeSegment.type === 'param') {\n if (baseSegment.value === '/') {\n return false\n }\n\n let _paramValue: string\n\n // If this param has prefix/suffix, we need to extract the actual parameter value\n if (routeSegment.prefixSegment || routeSegment.suffixSegment) {\n const prefix = routeSegment.prefixSegment || ''\n const suffix = routeSegment.suffixSegment || ''\n\n // Check if the base segment starts with prefix and ends with suffix\n const baseValue = baseSegment.value\n if (prefix && !baseValue.startsWith(prefix)) {\n return false\n }\n if (suffix && !baseValue.endsWith(suffix)) {\n return false\n }\n\n let paramValue = baseValue\n if (prefix && paramValue.startsWith(prefix)) {\n paramValue = paramValue.slice(prefix.length)\n }\n if (suffix && paramValue.endsWith(suffix)) {\n paramValue = paramValue.slice(\n 0,\n paramValue.length - suffix.length,\n )\n }\n\n _paramValue = decodeURIComponent(paramValue)\n } else {\n // If no prefix/suffix, just decode the base segment value\n _paramValue = decodeURIComponent(baseSegment.value)\n }\n\n params[routeSegment.value.substring(1)] = _paramValue\n }\n }\n\n if (!isLastBaseSegment && isLastRouteSegment) {\n params['**'] = joinPaths(baseSegments.slice(i + 1).map((d) => d.value))\n return !!matchLocation.fuzzy && routeSegment?.value !== '/'\n }\n }\n\n return true\n })()\n\n return isMatch ? params : undefined\n}\n"],"names":["last"],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ import { MatchLocation } from './RouterProvider.cjs';
2
+ import { AnyPathParams } from './route.cjs';
3
+ export interface Segment {
4
+ type: 'pathname' | 'param' | 'wildcard';
5
+ value: string;
6
+ prefixSegment?: string;
7
+ suffixSegment?: string;
8
+ }
9
+ export declare function joinPaths(paths: Array<string | undefined>): string;
10
+ export declare function cleanPath(path: string): string;
11
+ export declare function trimPathLeft(path: string): string;
12
+ export declare function trimPathRight(path: string): string;
13
+ export declare function trimPath(path: string): string;
14
+ export declare function removeTrailingSlash(value: string, basepath: string): string;
15
+ export declare function exactPathTest(pathName1: string, pathName2: string, basepath: string): boolean;
16
+ interface ResolvePathOptions {
17
+ basepath: string;
18
+ base: string;
19
+ to: string;
20
+ trailingSlash?: 'always' | 'never' | 'preserve';
21
+ caseSensitive?: boolean;
22
+ }
23
+ export declare function resolvePath({ basepath, base, to, trailingSlash, caseSensitive, }: ResolvePathOptions): string;
24
+ /**
25
+ * Required: `/foo/$bar` ✅
26
+ * Prefix and Suffix: `/foo/prefix${bar}suffix` ✅
27
+ * Wildcard: `/foo/$` ✅
28
+ * Wildcard with Prefix and Suffix: `/foo/prefix{$}suffix` ✅
29
+ *
30
+ * Future:
31
+ * Optional: `/foo/{-bar}`
32
+ * Optional named segment: `/foo/{bar}`
33
+ * Optional named segment with Prefix and Suffix: `/foo/prefix{-bar}suffix`
34
+ * Escape special characters:
35
+ * - `/foo/[$]` - Static route
36
+ * - `/foo/[$]{$foo} - Dynamic route with a static prefix of `$`
37
+ * - `/foo/{$foo}[$]` - Dynamic route with a static suffix of `$`
38
+ */
39
+ export declare function parsePathname(pathname?: string): Array<Segment>;
40
+ interface InterpolatePathOptions {
41
+ path?: string;
42
+ params: Record<string, unknown>;
43
+ leaveWildcards?: boolean;
44
+ leaveParams?: boolean;
45
+ decodeCharMap?: Map<string, string>;
46
+ }
47
+ type InterPolatePathResult = {
48
+ interpolatedPath: string;
49
+ usedParams: Record<string, unknown>;
50
+ isMissingParams: boolean;
51
+ };
52
+ export declare function interpolatePath({ path, params, leaveWildcards, leaveParams, decodeCharMap, }: InterpolatePathOptions): InterPolatePathResult;
53
+ export declare function matchPathname(basepath: string, currentPathname: string, matchLocation: Pick<MatchLocation, 'to' | 'fuzzy' | 'caseSensitive'>): AnyPathParams | undefined;
54
+ export declare function removeBasepath(basepath: string, pathname: string, caseSensitive?: boolean): string;
55
+ export declare function matchByPath(basepath: string, from: string, matchLocation: Pick<MatchLocation, 'to' | 'caseSensitive' | 'fuzzy'>): Record<string, string> | undefined;
56
+ export {};
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ function encode(obj, pfx) {
4
+ const normalizedObject = Object.entries(obj).flatMap(([key, value]) => {
5
+ if (Array.isArray(value)) {
6
+ return value.map((v) => [key, String(v)]);
7
+ } else {
8
+ return [[key, String(value)]];
9
+ }
10
+ });
11
+ const searchParams = new URLSearchParams(normalizedObject);
12
+ return (pfx || "") + searchParams.toString();
13
+ }
14
+ function toValue(str) {
15
+ if (!str) return "";
16
+ if (str === "false") return false;
17
+ if (str === "true") return true;
18
+ return +str * 0 === 0 && +str + "" === str ? +str : str;
19
+ }
20
+ function decode(str, pfx) {
21
+ const searchParamsPart = pfx ? str.slice(pfx.length) : str;
22
+ const searchParams = new URLSearchParams(searchParamsPart);
23
+ const entries = [...searchParams.entries()];
24
+ return entries.reduce((acc, [key, value]) => {
25
+ const previousValue = acc[key];
26
+ if (previousValue == null) {
27
+ acc[key] = toValue(value);
28
+ } else {
29
+ acc[key] = Array.isArray(previousValue) ? [...previousValue, toValue(value)] : [previousValue, toValue(value)];
30
+ }
31
+ return acc;
32
+ }, {});
33
+ }
34
+ exports.decode = decode;
35
+ exports.encode = encode;
36
+ //# sourceMappingURL=qss.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qss.cjs","sources":["../../src/qss.ts"],"sourcesContent":["/**\n * Program is a reimplementation of the `qss` package:\n * Copyright (c) Luke Edwards luke.edwards05@gmail.com, MIT License\n * https://github.com/lukeed/qss/blob/master/license.md\n *\n * This reimplementation uses modern browser APIs\n * (namely URLSearchParams) and TypeScript while still\n * maintaining the original functionality and interface.\n */\n\n/**\n * Encodes an object into a query string.\n * @param obj - The object to encode into a query string.\n * @param [pfx] - An optional prefix to add before the query string.\n * @returns The encoded query string.\n * @example\n * ```\n * // Example input: encode({ token: 'foo', key: 'value' })\n * // Expected output: \"token=foo&key=value\"\n * ```\n */\nexport function encode(obj: any, pfx?: string) {\n const normalizedObject = Object.entries(obj).flatMap(([key, value]) => {\n if (Array.isArray(value)) {\n return value.map((v) => [key, String(v)])\n } else {\n return [[key, String(value)]]\n }\n })\n\n const searchParams = new URLSearchParams(normalizedObject)\n\n return (pfx || '') + searchParams.toString()\n}\n\n/**\n * Converts a string value to its appropriate type (string, number, boolean).\n * @param mix - The string value to convert.\n * @returns The converted value.\n * @example\n * // Example input: toValue(\"123\")\n * // Expected output: 123\n */\nfunction toValue(str: unknown) {\n if (!str) return ''\n\n if (str === 'false') return false\n if (str === 'true') return true\n return +str * 0 === 0 && +str + '' === str ? +str : str\n}\n\n/**\n * Decodes a query string into an object.\n * @param str - The query string to decode.\n * @param [pfx] - An optional prefix to filter out from the query string.\n * @returns The decoded key-value pairs in an object format.\n * @example\n * // Example input: decode(\"token=foo&key=value\")\n * // Expected output: { \"token\": \"foo\", \"key\": \"value\" }\n */\nexport function decode(str: any, pfx?: string): any {\n const searchParamsPart = pfx ? str.slice(pfx.length) : str\n const searchParams = new URLSearchParams(searchParamsPart)\n\n const entries = [...searchParams.entries()]\n\n return entries.reduce<Record<string, unknown>>((acc, [key, value]) => {\n const previousValue = acc[key]\n if (previousValue == null) {\n acc[key] = toValue(value)\n } else {\n acc[key] = Array.isArray(previousValue)\n ? [...previousValue, toValue(value)]\n : [previousValue, toValue(value)]\n }\n\n return acc\n }, {})\n}\n"],"names":[],"mappings":";;AAqBgB,SAAA,OAAO,KAAU,KAAc;AACvC,QAAA,mBAAmB,OAAO,QAAQ,GAAG,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACjE,QAAA,MAAM,QAAQ,KAAK,GAAG;AACjB,aAAA,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC;AAAA,IAAA,OACnC;AACL,aAAO,CAAC,CAAC,KAAK,OAAO,KAAK,CAAC,CAAC;AAAA,IAAA;AAAA,EAC9B,CACD;AAEK,QAAA,eAAe,IAAI,gBAAgB,gBAAgB;AAEjD,UAAA,OAAO,MAAM,aAAa,SAAS;AAC7C;AAUA,SAAS,QAAQ,KAAc;AACzB,MAAA,CAAC,IAAY,QAAA;AAEb,MAAA,QAAQ,QAAgB,QAAA;AACxB,MAAA,QAAQ,OAAe,QAAA;AACpB,SAAA,CAAC,MAAM,MAAM,KAAK,CAAC,MAAM,OAAO,MAAM,CAAC,MAAM;AACtD;AAWgB,SAAA,OAAO,KAAU,KAAmB;AAClD,QAAM,mBAAmB,MAAM,IAAI,MAAM,IAAI,MAAM,IAAI;AACjD,QAAA,eAAe,IAAI,gBAAgB,gBAAgB;AAEzD,QAAM,UAAU,CAAC,GAAG,aAAa,SAAS;AAE1C,SAAO,QAAQ,OAAgC,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM;AAC9D,UAAA,gBAAgB,IAAI,GAAG;AAC7B,QAAI,iBAAiB,MAAM;AACrB,UAAA,GAAG,IAAI,QAAQ,KAAK;AAAA,IAAA,OACnB;AACL,UAAI,GAAG,IAAI,MAAM,QAAQ,aAAa,IAClC,CAAC,GAAG,eAAe,QAAQ,KAAK,CAAC,IACjC,CAAC,eAAe,QAAQ,KAAK,CAAC;AAAA,IAAA;AAG7B,WAAA;AAAA,EACT,GAAG,EAAE;AACP;;;"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Program is a reimplementation of the `qss` package:
3
+ * Copyright (c) Luke Edwards luke.edwards05@gmail.com, MIT License
4
+ * https://github.com/lukeed/qss/blob/master/license.md
5
+ *
6
+ * This reimplementation uses modern browser APIs
7
+ * (namely URLSearchParams) and TypeScript while still
8
+ * maintaining the original functionality and interface.
9
+ */
10
+ /**
11
+ * Encodes an object into a query string.
12
+ * @param obj - The object to encode into a query string.
13
+ * @param [pfx] - An optional prefix to add before the query string.
14
+ * @returns The encoded query string.
15
+ * @example
16
+ * ```
17
+ * // Example input: encode({ token: 'foo', key: 'value' })
18
+ * // Expected output: "token=foo&key=value"
19
+ * ```
20
+ */
21
+ export declare function encode(obj: any, pfx?: string): string;
22
+ /**
23
+ * Decodes a query string into an object.
24
+ * @param str - The query string to decode.
25
+ * @param [pfx] - An optional prefix to filter out from the query string.
26
+ * @returns The decoded key-value pairs in an object format.
27
+ * @example
28
+ * // Example input: decode("token=foo&key=value")
29
+ * // Expected output: { "token": "foo", "key": "value" }
30
+ */
31
+ export declare function decode(str: any, pfx?: string): any;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ function redirect(opts) {
4
+ opts.statusCode = opts.statusCode || opts.code || 307;
5
+ if (!opts.reloadDocument) {
6
+ try {
7
+ new URL(`${opts.href}`);
8
+ opts.reloadDocument = true;
9
+ } catch {
10
+ }
11
+ }
12
+ const headers = new Headers(opts.headers || {});
13
+ if (opts.href && headers.get("Location") === null) {
14
+ headers.set("Location", opts.href);
15
+ }
16
+ const response = new Response(null, {
17
+ status: opts.statusCode,
18
+ headers
19
+ });
20
+ response.options = opts;
21
+ if (opts.throw) {
22
+ throw response;
23
+ }
24
+ return response;
25
+ }
26
+ function isRedirect(obj) {
27
+ return obj instanceof Response && !!obj.options;
28
+ }
29
+ function isResolvedRedirect(obj) {
30
+ return isRedirect(obj) && !!obj.options.href;
31
+ }
32
+ function parseRedirect(obj) {
33
+ if (typeof obj === "object" && obj.isSerializedRedirect) {
34
+ return redirect(obj);
35
+ }
36
+ return void 0;
37
+ }
38
+ exports.isRedirect = isRedirect;
39
+ exports.isResolvedRedirect = isResolvedRedirect;
40
+ exports.parseRedirect = parseRedirect;
41
+ exports.redirect = redirect;
42
+ //# sourceMappingURL=redirect.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redirect.cjs","sources":["../../src/redirect.ts"],"sourcesContent":["import type { NavigateOptions } from './link'\nimport type { AnyRouter, RegisteredRouter } from './router'\n\nexport type AnyRedirect = Redirect<any, any, any, any, any>\n\n/**\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RedirectType)\n */\nexport type Redirect<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = undefined,\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n> = Response & {\n options: NavigateOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>\n redirectHandled?: boolean\n}\n\nexport type RedirectOptions<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string | undefined = undefined,\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '.',\n> = {\n href?: string\n /**\n * @deprecated Use `statusCode` instead\n **/\n code?: number\n /**\n * The HTTP status code to use when redirecting.\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RedirectType#statuscode-property)\n */\n statusCode?: number\n /**\n * If provided, will throw the redirect object instead of returning it. This can be useful in places where `throwing` in a function might cause it to have a return type of `never`. In that case, you can use `redirect({ throw: true })` to throw the redirect object instead of returning it.\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RedirectType#throw-property)\n */\n throw?: any\n /**\n * The HTTP headers to use when redirecting.\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RedirectType#headers-property)\n */\n headers?: HeadersInit\n} & NavigateOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>\n\nexport type ResolvedRedirect<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string = string,\n TTo extends string = '',\n TMaskFrom extends string = TFrom,\n TMaskTo extends string = '',\n> = Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>\n\nexport function redirect<\n TRouter extends AnyRouter = RegisteredRouter,\n const TTo extends string | undefined = '.',\n const TFrom extends string = string,\n const TMaskFrom extends string = TFrom,\n const TMaskTo extends string = '',\n>(\n opts: RedirectOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n): Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> {\n opts.statusCode = opts.statusCode || opts.code || 307\n\n if (!opts.reloadDocument) {\n try {\n new URL(`${opts.href}`)\n opts.reloadDocument = true\n } catch {}\n }\n\n const headers = new Headers(opts.headers || {})\n if (opts.href && headers.get('Location') === null) {\n headers.set('Location', opts.href)\n }\n\n const response = new Response(null, {\n status: opts.statusCode,\n headers,\n })\n\n ;(response as Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>).options =\n opts\n\n if (opts.throw) {\n throw response\n }\n\n return response as Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>\n}\n\nexport function isRedirect(obj: any): obj is AnyRedirect {\n return obj instanceof Response && !!(obj as any).options\n}\n\nexport function isResolvedRedirect(\n obj: any,\n): obj is AnyRedirect & { options: { href: string } } {\n return isRedirect(obj) && !!obj.options.href\n}\n\nexport function parseRedirect(obj: any) {\n if (typeof obj === 'object' && obj.isSerializedRedirect) {\n return redirect(obj)\n }\n\n return undefined\n}\n"],"names":[],"mappings":";;AAwDO,SAAS,SAOd,MACmD;AACnD,OAAK,aAAa,KAAK,cAAc,KAAK,QAAQ;AAE9C,MAAA,CAAC,KAAK,gBAAgB;AACpB,QAAA;AACF,UAAI,IAAI,GAAG,KAAK,IAAI,EAAE;AACtB,WAAK,iBAAiB;AAAA,IAAA,QAChB;AAAA,IAAA;AAAA,EAAC;AAGX,QAAM,UAAU,IAAI,QAAQ,KAAK,WAAW,CAAA,CAAE;AAC9C,MAAI,KAAK,QAAQ,QAAQ,IAAI,UAAU,MAAM,MAAM;AACzC,YAAA,IAAI,YAAY,KAAK,IAAI;AAAA,EAAA;AAG7B,QAAA,WAAW,IAAI,SAAS,MAAM;AAAA,IAClC,QAAQ,KAAK;AAAA,IACb;AAAA,EAAA,CACD;AAEC,WAA+D,UAC/D;AAEF,MAAI,KAAK,OAAO;AACR,UAAA;AAAA,EAAA;AAGD,SAAA;AACT;AAEO,SAAS,WAAW,KAA8B;AACvD,SAAO,eAAe,YAAY,CAAC,CAAE,IAAY;AACnD;AAEO,SAAS,mBACd,KACoD;AACpD,SAAO,WAAW,GAAG,KAAK,CAAC,CAAC,IAAI,QAAQ;AAC1C;AAEO,SAAS,cAAc,KAAU;AACtC,MAAI,OAAO,QAAQ,YAAY,IAAI,sBAAsB;AACvD,WAAO,SAAS,GAAG;AAAA,EAAA;AAGd,SAAA;AACT;;;;;"}