@tanstack/router-core 0.0.1-beta.9 → 1.97.24

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 (140) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +5 -0
  3. package/dist/cjs/Matches.cjs +13 -0
  4. package/dist/cjs/Matches.cjs.map +1 -0
  5. package/dist/cjs/Matches.d.cts +28 -0
  6. package/dist/cjs/RouterProvider.d.cts +18 -0
  7. package/dist/cjs/defer.cjs +25 -0
  8. package/dist/cjs/defer.cjs.map +1 -0
  9. package/dist/cjs/defer.d.cts +20 -0
  10. package/dist/cjs/index.cjs +50 -0
  11. package/dist/cjs/index.cjs.map +1 -0
  12. package/dist/cjs/index.d.cts +25 -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 +51 -0
  16. package/dist/cjs/location.d.cts +12 -0
  17. package/dist/cjs/manifest.d.cts +24 -0
  18. package/dist/cjs/path.cjs +289 -0
  19. package/dist/cjs/path.cjs.map +1 -0
  20. package/dist/cjs/path.d.cts +34 -0
  21. package/dist/cjs/qss.cjs +51 -0
  22. package/dist/cjs/qss.cjs.map +1 -0
  23. package/dist/cjs/qss.d.cts +27 -0
  24. package/dist/cjs/root.cjs +5 -0
  25. package/dist/cjs/root.cjs.map +1 -0
  26. package/dist/cjs/root.d.cts +2 -0
  27. package/dist/cjs/route.d.cts +148 -0
  28. package/dist/cjs/router.cjs +19 -0
  29. package/dist/cjs/router.cjs.map +1 -0
  30. package/dist/cjs/router.d.cts +31 -0
  31. package/dist/cjs/searchMiddleware.cjs +42 -0
  32. package/dist/cjs/searchMiddleware.cjs.map +1 -0
  33. package/dist/cjs/searchMiddleware.d.cts +5 -0
  34. package/dist/cjs/searchParams.cjs +61 -0
  35. package/dist/cjs/searchParams.cjs.map +1 -0
  36. package/dist/cjs/searchParams.d.cts +7 -0
  37. package/dist/cjs/serializer.d.cts +15 -0
  38. package/dist/cjs/structuralSharing.d.cts +4 -0
  39. package/dist/cjs/utils.cjs +155 -0
  40. package/dist/cjs/utils.cjs.map +1 -0
  41. package/dist/cjs/utils.d.cts +81 -0
  42. package/dist/cjs/validators.d.cts +51 -0
  43. package/dist/esm/Matches.d.ts +28 -0
  44. package/dist/esm/Matches.js +13 -0
  45. package/dist/esm/Matches.js.map +1 -0
  46. package/dist/esm/RouterProvider.d.ts +18 -0
  47. package/dist/esm/defer.d.ts +20 -0
  48. package/dist/esm/defer.js +25 -0
  49. package/dist/esm/defer.js.map +1 -0
  50. package/dist/esm/index.d.ts +25 -0
  51. package/dist/esm/index.js +50 -0
  52. package/dist/esm/index.js.map +1 -0
  53. package/dist/esm/link.d.ts +51 -0
  54. package/dist/esm/link.js +5 -0
  55. package/dist/esm/link.js.map +1 -0
  56. package/dist/esm/location.d.ts +12 -0
  57. package/dist/esm/manifest.d.ts +24 -0
  58. package/dist/esm/path.d.ts +34 -0
  59. package/dist/esm/path.js +289 -0
  60. package/dist/esm/path.js.map +1 -0
  61. package/dist/esm/qss.d.ts +27 -0
  62. package/dist/esm/qss.js +51 -0
  63. package/dist/esm/qss.js.map +1 -0
  64. package/dist/esm/root.d.ts +2 -0
  65. package/dist/esm/root.js +5 -0
  66. package/dist/esm/root.js.map +1 -0
  67. package/dist/esm/route.d.ts +148 -0
  68. package/dist/esm/router.d.ts +31 -0
  69. package/dist/esm/router.js +19 -0
  70. package/dist/esm/router.js.map +1 -0
  71. package/dist/esm/searchMiddleware.d.ts +5 -0
  72. package/dist/esm/searchMiddleware.js +42 -0
  73. package/dist/esm/searchMiddleware.js.map +1 -0
  74. package/dist/esm/searchParams.d.ts +7 -0
  75. package/dist/esm/searchParams.js +61 -0
  76. package/dist/esm/searchParams.js.map +1 -0
  77. package/dist/esm/serializer.d.ts +15 -0
  78. package/dist/esm/structuralSharing.d.ts +4 -0
  79. package/dist/esm/utils.d.ts +81 -0
  80. package/dist/esm/utils.js +155 -0
  81. package/dist/esm/utils.js.map +1 -0
  82. package/dist/esm/validators.d.ts +51 -0
  83. package/package.json +35 -32
  84. package/src/Matches.ts +94 -0
  85. package/src/RouterProvider.ts +20 -0
  86. package/src/defer.ts +52 -0
  87. package/src/index.ts +206 -19
  88. package/src/link.ts +122 -300
  89. package/src/location.ts +13 -0
  90. package/src/manifest.ts +32 -0
  91. package/src/path.ts +238 -47
  92. package/src/qss.ts +56 -19
  93. package/src/root.ts +2 -0
  94. package/src/route.ts +296 -223
  95. package/src/router.ts +34 -1281
  96. package/src/searchMiddleware.ts +54 -0
  97. package/src/searchParams.ts +43 -20
  98. package/src/serializer.ts +24 -0
  99. package/src/structuralSharing.ts +7 -0
  100. package/src/utils.ts +314 -75
  101. package/src/validators.ts +121 -0
  102. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js +0 -33
  103. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js.map +0 -1
  104. package/build/cjs/node_modules/@babel/runtime/helpers/esm/extends.js +0 -33
  105. package/build/cjs/node_modules/@babel/runtime/helpers/esm/extends.js.map +0 -1
  106. package/build/cjs/node_modules/history/index.js +0 -815
  107. package/build/cjs/node_modules/history/index.js.map +0 -1
  108. package/build/cjs/node_modules/tiny-invariant/dist/esm/tiny-invariant.js +0 -30
  109. package/build/cjs/node_modules/tiny-invariant/dist/esm/tiny-invariant.js.map +0 -1
  110. package/build/cjs/packages/router-core/src/index.js +0 -58
  111. package/build/cjs/packages/router-core/src/index.js.map +0 -1
  112. package/build/cjs/packages/router-core/src/path.js +0 -222
  113. package/build/cjs/packages/router-core/src/path.js.map +0 -1
  114. package/build/cjs/packages/router-core/src/qss.js +0 -71
  115. package/build/cjs/packages/router-core/src/qss.js.map +0 -1
  116. package/build/cjs/packages/router-core/src/route.js +0 -150
  117. package/build/cjs/packages/router-core/src/route.js.map +0 -1
  118. package/build/cjs/packages/router-core/src/routeConfig.js +0 -69
  119. package/build/cjs/packages/router-core/src/routeConfig.js.map +0 -1
  120. package/build/cjs/packages/router-core/src/routeMatch.js +0 -266
  121. package/build/cjs/packages/router-core/src/routeMatch.js.map +0 -1
  122. package/build/cjs/packages/router-core/src/router.js +0 -822
  123. package/build/cjs/packages/router-core/src/router.js.map +0 -1
  124. package/build/cjs/packages/router-core/src/searchParams.js +0 -70
  125. package/build/cjs/packages/router-core/src/searchParams.js.map +0 -1
  126. package/build/cjs/packages/router-core/src/utils.js +0 -125
  127. package/build/cjs/packages/router-core/src/utils.js.map +0 -1
  128. package/build/esm/index.js +0 -2481
  129. package/build/esm/index.js.map +0 -1
  130. package/build/stats-html.html +0 -4034
  131. package/build/stats-react.json +0 -493
  132. package/build/types/index.d.ts +0 -618
  133. package/build/umd/index.development.js +0 -2514
  134. package/build/umd/index.development.js.map +0 -1
  135. package/build/umd/index.production.js +0 -12
  136. package/build/umd/index.production.js.map +0 -1
  137. package/src/frameworks.ts +0 -12
  138. package/src/routeConfig.ts +0 -495
  139. package/src/routeInfo.ts +0 -228
  140. package/src/routeMatch.ts +0 -374
@@ -0,0 +1,34 @@
1
+ import { MatchLocation } from './RouterProvider.js';
2
+ import { AnyPathParams } from './route.js';
3
+ export interface Segment {
4
+ type: 'pathname' | 'param' | 'wildcard';
5
+ value: string;
6
+ }
7
+ export declare function joinPaths(paths: Array<string | undefined>): string;
8
+ export declare function cleanPath(path: string): string;
9
+ export declare function trimPathLeft(path: string): string;
10
+ export declare function trimPathRight(path: string): string;
11
+ export declare function trimPath(path: string): string;
12
+ export declare function removeTrailingSlash(value: string, basepath: string): string;
13
+ export declare function exactPathTest(pathName1: string, pathName2: string, basepath: string): boolean;
14
+ interface ResolvePathOptions {
15
+ basepath: string;
16
+ base: string;
17
+ to: string;
18
+ trailingSlash?: 'always' | 'never' | 'preserve';
19
+ caseSensitive?: boolean;
20
+ }
21
+ export declare function resolvePath({ basepath, base, to, trailingSlash, caseSensitive, }: ResolvePathOptions): string;
22
+ export declare function parsePathname(pathname?: string): Array<Segment>;
23
+ interface InterpolatePathOptions {
24
+ path?: string;
25
+ params: Record<string, unknown>;
26
+ leaveWildcards?: boolean;
27
+ leaveParams?: boolean;
28
+ decodeCharMap?: Map<string, string>;
29
+ }
30
+ export declare function interpolatePath({ path, params, leaveWildcards, leaveParams, decodeCharMap, }: InterpolatePathOptions): string;
31
+ export declare function matchPathname(basepath: string, currentPathname: string, matchLocation: Pick<MatchLocation, 'to' | 'fuzzy' | 'caseSensitive'>): AnyPathParams | undefined;
32
+ export declare function removeBasepath(basepath: string, pathname: string, caseSensitive?: boolean): string;
33
+ export declare function matchByPath(basepath: string, from: string, matchLocation: Pick<MatchLocation, 'to' | 'caseSensitive' | 'fuzzy'>): Record<string, string> | undefined;
34
+ export {};
@@ -0,0 +1,289 @@
1
+ import { last } from "./utils.js";
2
+ function joinPaths(paths) {
3
+ return cleanPath(
4
+ paths.filter((val) => {
5
+ return val !== void 0;
6
+ }).join("/")
7
+ );
8
+ }
9
+ function cleanPath(path) {
10
+ return path.replace(/\/{2,}/g, "/");
11
+ }
12
+ function trimPathLeft(path) {
13
+ return path === "/" ? path : path.replace(/^\/{1,}/, "");
14
+ }
15
+ function trimPathRight(path) {
16
+ return path === "/" ? path : path.replace(/\/{1,}$/, "");
17
+ }
18
+ function trimPath(path) {
19
+ return trimPathRight(trimPathLeft(path));
20
+ }
21
+ function removeTrailingSlash(value, basepath) {
22
+ if (value.endsWith("/") && value !== "/" && value !== `${basepath}/`) {
23
+ return value.slice(0, -1);
24
+ }
25
+ return value;
26
+ }
27
+ function exactPathTest(pathName1, pathName2, basepath) {
28
+ return removeTrailingSlash(pathName1, basepath) === removeTrailingSlash(pathName2, basepath);
29
+ }
30
+ function resolvePath({
31
+ basepath,
32
+ base,
33
+ to,
34
+ trailingSlash = "never",
35
+ caseSensitive
36
+ }) {
37
+ var _a, _b;
38
+ base = removeBasepath(basepath, base, caseSensitive);
39
+ to = removeBasepath(basepath, to, caseSensitive);
40
+ let baseSegments = parsePathname(base);
41
+ const toSegments = parsePathname(to);
42
+ if (baseSegments.length > 1 && ((_a = last(baseSegments)) == null ? void 0 : _a.value) === "/") {
43
+ baseSegments.pop();
44
+ }
45
+ toSegments.forEach((toSegment, index) => {
46
+ if (toSegment.value === "/") {
47
+ if (!index) {
48
+ baseSegments = [toSegment];
49
+ } else if (index === toSegments.length - 1) {
50
+ baseSegments.push(toSegment);
51
+ } else ;
52
+ } else if (toSegment.value === "..") {
53
+ baseSegments.pop();
54
+ } else if (toSegment.value === ".") ;
55
+ else {
56
+ baseSegments.push(toSegment);
57
+ }
58
+ });
59
+ if (baseSegments.length > 1) {
60
+ if (((_b = last(baseSegments)) == null ? void 0 : _b.value) === "/") {
61
+ if (trailingSlash === "never") {
62
+ baseSegments.pop();
63
+ }
64
+ } else if (trailingSlash === "always") {
65
+ baseSegments.push({ type: "pathname", value: "/" });
66
+ }
67
+ }
68
+ const joined = joinPaths([basepath, ...baseSegments.map((d) => d.value)]);
69
+ return cleanPath(joined);
70
+ }
71
+ function parsePathname(pathname) {
72
+ if (!pathname) {
73
+ return [];
74
+ }
75
+ pathname = cleanPath(pathname);
76
+ const segments = [];
77
+ if (pathname.slice(0, 1) === "/") {
78
+ pathname = pathname.substring(1);
79
+ segments.push({
80
+ type: "pathname",
81
+ value: "/"
82
+ });
83
+ }
84
+ if (!pathname) {
85
+ return segments;
86
+ }
87
+ const split = pathname.split("/").filter(Boolean);
88
+ segments.push(
89
+ ...split.map((part) => {
90
+ if (part === "$" || part === "*") {
91
+ return {
92
+ type: "wildcard",
93
+ value: part
94
+ };
95
+ }
96
+ if (part.charAt(0) === "$") {
97
+ return {
98
+ type: "param",
99
+ value: part
100
+ };
101
+ }
102
+ return {
103
+ type: "pathname",
104
+ value: decodeURI(part)
105
+ };
106
+ })
107
+ );
108
+ if (pathname.slice(-1) === "/") {
109
+ pathname = pathname.substring(1);
110
+ segments.push({
111
+ type: "pathname",
112
+ value: "/"
113
+ });
114
+ }
115
+ return segments;
116
+ }
117
+ function interpolatePath({
118
+ path,
119
+ params,
120
+ leaveWildcards,
121
+ leaveParams,
122
+ decodeCharMap
123
+ }) {
124
+ const interpolatedPathSegments = parsePathname(path);
125
+ const encodedParams = {};
126
+ for (const [key, value] of Object.entries(params)) {
127
+ const isValueString = typeof value === "string";
128
+ if (["*", "_splat"].includes(key)) {
129
+ encodedParams[key] = isValueString ? encodeURI(value) : value;
130
+ } else {
131
+ encodedParams[key] = isValueString ? encodePathParam(value, decodeCharMap) : value;
132
+ }
133
+ }
134
+ return joinPaths(
135
+ interpolatedPathSegments.map((segment) => {
136
+ if (segment.type === "wildcard") {
137
+ const value = encodedParams._splat;
138
+ if (leaveWildcards) return `${segment.value}${value ?? ""}`;
139
+ return value;
140
+ }
141
+ if (segment.type === "param") {
142
+ if (leaveParams) {
143
+ const value = encodedParams[segment.value];
144
+ return `${segment.value}${value ?? ""}`;
145
+ }
146
+ return encodedParams[segment.value.substring(1)] ?? "undefined";
147
+ }
148
+ return segment.value;
149
+ })
150
+ );
151
+ }
152
+ function encodePathParam(value, decodeCharMap) {
153
+ let encoded = encodeURIComponent(value);
154
+ if (decodeCharMap) {
155
+ for (const [encodedChar, char] of decodeCharMap) {
156
+ encoded = encoded.replaceAll(encodedChar, char);
157
+ }
158
+ }
159
+ return encoded;
160
+ }
161
+ function matchPathname(basepath, currentPathname, matchLocation) {
162
+ const pathParams = matchByPath(basepath, currentPathname, matchLocation);
163
+ if (matchLocation.to && !pathParams) {
164
+ return;
165
+ }
166
+ return pathParams ?? {};
167
+ }
168
+ function removeBasepath(basepath, pathname, caseSensitive = false) {
169
+ const normalizedBasepath = caseSensitive ? basepath : basepath.toLowerCase();
170
+ const normalizedPathname = caseSensitive ? pathname : pathname.toLowerCase();
171
+ switch (true) {
172
+ // default behaviour is to serve app from the root - pathname
173
+ // left untouched
174
+ case normalizedBasepath === "/":
175
+ return pathname;
176
+ // shortcut for removing the basepath if it matches the pathname
177
+ case normalizedPathname === normalizedBasepath:
178
+ return "";
179
+ // in case pathname is shorter than basepath - there is
180
+ // nothing to remove
181
+ case pathname.length < basepath.length:
182
+ return pathname;
183
+ // avoid matching partial segments - strict equality handled
184
+ // earlier, otherwise, basepath separated from pathname with
185
+ // separator, therefore lack of separator means partial
186
+ // segment match (`/app` should not match `/application`)
187
+ case normalizedPathname[normalizedBasepath.length] !== "/":
188
+ return pathname;
189
+ // remove the basepath from the pathname if it starts with it
190
+ case normalizedPathname.startsWith(normalizedBasepath):
191
+ return pathname.slice(basepath.length);
192
+ // otherwise, return the pathname as is
193
+ default:
194
+ return pathname;
195
+ }
196
+ }
197
+ function matchByPath(basepath, from, matchLocation) {
198
+ if (basepath !== "/" && !from.startsWith(basepath)) {
199
+ return void 0;
200
+ }
201
+ from = removeBasepath(basepath, from, matchLocation.caseSensitive);
202
+ const to = removeBasepath(
203
+ basepath,
204
+ `${matchLocation.to ?? "$"}`,
205
+ matchLocation.caseSensitive
206
+ );
207
+ const baseSegments = parsePathname(from);
208
+ const routeSegments = parsePathname(to);
209
+ if (!from.startsWith("/")) {
210
+ baseSegments.unshift({
211
+ type: "pathname",
212
+ value: "/"
213
+ });
214
+ }
215
+ if (!to.startsWith("/")) {
216
+ routeSegments.unshift({
217
+ type: "pathname",
218
+ value: "/"
219
+ });
220
+ }
221
+ const params = {};
222
+ const isMatch = (() => {
223
+ for (let i = 0; i < Math.max(baseSegments.length, routeSegments.length); i++) {
224
+ const baseSegment = baseSegments[i];
225
+ const routeSegment = routeSegments[i];
226
+ const isLastBaseSegment = i >= baseSegments.length - 1;
227
+ const isLastRouteSegment = i >= routeSegments.length - 1;
228
+ if (routeSegment) {
229
+ if (routeSegment.type === "wildcard") {
230
+ const _splat = decodeURI(
231
+ joinPaths(baseSegments.slice(i).map((d) => d.value))
232
+ );
233
+ params["*"] = _splat;
234
+ params["_splat"] = _splat;
235
+ return true;
236
+ }
237
+ if (routeSegment.type === "pathname") {
238
+ if (routeSegment.value === "/" && !(baseSegment == null ? void 0 : baseSegment.value)) {
239
+ return true;
240
+ }
241
+ if (baseSegment) {
242
+ if (matchLocation.caseSensitive) {
243
+ if (routeSegment.value !== baseSegment.value) {
244
+ return false;
245
+ }
246
+ } else if (routeSegment.value.toLowerCase() !== baseSegment.value.toLowerCase()) {
247
+ return false;
248
+ }
249
+ }
250
+ }
251
+ if (!baseSegment) {
252
+ return false;
253
+ }
254
+ if (routeSegment.type === "param") {
255
+ if (baseSegment.value === "/") {
256
+ return false;
257
+ }
258
+ if (baseSegment.value.charAt(0) !== "$") {
259
+ params[routeSegment.value.substring(1)] = decodeURIComponent(
260
+ baseSegment.value
261
+ );
262
+ }
263
+ }
264
+ }
265
+ if (!isLastBaseSegment && isLastRouteSegment) {
266
+ params["**"] = joinPaths(baseSegments.slice(i + 1).map((d) => d.value));
267
+ return !!matchLocation.fuzzy && (routeSegment == null ? void 0 : routeSegment.value) !== "/";
268
+ }
269
+ }
270
+ return true;
271
+ })();
272
+ return isMatch ? params : void 0;
273
+ }
274
+ export {
275
+ cleanPath,
276
+ exactPathTest,
277
+ interpolatePath,
278
+ joinPaths,
279
+ matchByPath,
280
+ matchPathname,
281
+ parsePathname,
282
+ removeBasepath,
283
+ removeTrailingSlash,
284
+ resolvePath,
285
+ trimPath,
286
+ trimPathLeft,
287
+ trimPathRight
288
+ };
289
+ //# sourceMappingURL=path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path.js","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}\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 joined = joinPaths([basepath, ...baseSegments.map((d) => d.value)])\n return cleanPath(joined)\n}\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 if (part === '$' || part === '*') {\n return {\n type: 'wildcard',\n value: part,\n }\n }\n\n if (part.charAt(0) === '$') {\n return {\n type: 'param',\n value: part,\n }\n }\n\n return {\n type: 'pathname',\n value: 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\nexport function interpolatePath({\n path,\n params,\n leaveWildcards,\n leaveParams,\n decodeCharMap,\n}: InterpolatePathOptions) {\n const interpolatedPathSegments = parsePathname(path)\n const encodedParams: any = {}\n\n for (const [key, value] of Object.entries(params)) {\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 encodedParams[key] = isValueString ? encodeURI(value) : value\n } else {\n encodedParams[key] = isValueString\n ? encodePathParam(value, decodeCharMap)\n : value\n }\n }\n\n return joinPaths(\n interpolatedPathSegments.map((segment) => {\n if (segment.type === 'wildcard') {\n const value = encodedParams._splat\n if (leaveWildcards) return `${segment.value}${value ?? ''}`\n return value\n }\n\n if (segment.type === 'param') {\n if (leaveParams) {\n const value = encodedParams[segment.value]\n return `${segment.value}${value ?? ''}`\n }\n return encodedParams![segment.value.substring(1)] ?? 'undefined'\n }\n\n return segment.value\n }),\n )\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 const _splat = decodeURI(\n joinPaths(baseSegments.slice(i).map((d) => d.value)),\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 if (baseSegment.value.charAt(0) !== '$') {\n params[routeSegment.value.substring(1)] = decodeURIComponent(\n baseSegment.value,\n )\n }\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":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Program uses a modified version 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
+ /**
7
+ * Encodes an object into a query string.
8
+ * @param obj - The object to encode into a query string.
9
+ * @param [pfx] - An optional prefix to add before the query string.
10
+ * @returns The encoded query string.
11
+ * @example
12
+ * ```
13
+ * // Example input: encode({ token: 'foo', key: 'value' })
14
+ * // Expected output: "token=foo&key=value"
15
+ * ```
16
+ */
17
+ export declare function encode(obj: any, pfx?: string): string;
18
+ /**
19
+ * Decodes a query string into an object.
20
+ * @param str - The query string to decode.
21
+ * @param [pfx] - An optional prefix to filter out from the query string.
22
+ * @returns The decoded key-value pairs in an object format.
23
+ * @example
24
+ * // Example input: decode("token=foo&key=value")
25
+ * // Expected output: { "token": "foo", "key": "value" }
26
+ */
27
+ export declare function decode(str: any, pfx?: string): any;
@@ -0,0 +1,51 @@
1
+ function encode(obj, pfx) {
2
+ let k, i, tmp, str = "";
3
+ for (k in obj) {
4
+ if ((tmp = obj[k]) !== void 0) {
5
+ if (Array.isArray(tmp)) {
6
+ for (i = 0; i < tmp.length; i++) {
7
+ str && (str += "&");
8
+ str += encodeURIComponent(k) + "=" + encodeURIComponent(tmp[i]);
9
+ }
10
+ } else {
11
+ str && (str += "&");
12
+ str += encodeURIComponent(k) + "=" + encodeURIComponent(tmp);
13
+ }
14
+ }
15
+ }
16
+ return (pfx || "") + str;
17
+ }
18
+ function toValue(mix) {
19
+ if (!mix) return "";
20
+ const str = decodeURIComponent(mix);
21
+ if (str === "false") return false;
22
+ if (str === "true") return true;
23
+ return +str * 0 === 0 && +str + "" === str ? +str : str;
24
+ }
25
+ function decode(str, pfx) {
26
+ let tmp, k;
27
+ const out = {}, arr = (pfx ? str.substr(pfx.length) : str).split("&");
28
+ while (tmp = arr.shift()) {
29
+ const equalIndex = tmp.indexOf("=");
30
+ if (equalIndex !== -1) {
31
+ k = tmp.slice(0, equalIndex);
32
+ k = decodeURIComponent(k);
33
+ const value = tmp.slice(equalIndex + 1);
34
+ if (out[k] !== void 0) {
35
+ out[k] = [].concat(out[k], toValue(value));
36
+ } else {
37
+ out[k] = toValue(value);
38
+ }
39
+ } else {
40
+ k = tmp;
41
+ k = decodeURIComponent(k);
42
+ out[k] = "";
43
+ }
44
+ }
45
+ return out;
46
+ }
47
+ export {
48
+ decode,
49
+ encode
50
+ };
51
+ //# sourceMappingURL=qss.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qss.js","sources":["../../src/qss.ts"],"sourcesContent":["/**\n * Program uses a modified version 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\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 let k,\n i,\n tmp,\n str = ''\n\n for (k in obj) {\n if ((tmp = obj[k]) !== void 0) {\n if (Array.isArray(tmp)) {\n for (i = 0; i < tmp.length; i++) {\n str && (str += '&')\n str += encodeURIComponent(k) + '=' + encodeURIComponent(tmp[i])\n }\n } else {\n str && (str += '&')\n str += encodeURIComponent(k) + '=' + encodeURIComponent(tmp)\n }\n }\n }\n\n return (pfx || '') + str\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(mix: any) {\n if (!mix) return ''\n const str = decodeURIComponent(mix)\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) {\n let tmp, k\n const out: any = {},\n arr = (pfx ? str.substr(pfx.length) : str).split('&')\n\n while ((tmp = arr.shift())) {\n const equalIndex = tmp.indexOf('=')\n if (equalIndex !== -1) {\n k = tmp.slice(0, equalIndex)\n k = decodeURIComponent(k)\n const value = tmp.slice(equalIndex + 1)\n if (out[k] !== void 0) {\n // @ts-expect-error\n out[k] = [].concat(out[k], toValue(value))\n } else {\n out[k] = toValue(value)\n }\n } else {\n k = tmp\n k = decodeURIComponent(k)\n out[k] = ''\n }\n }\n\n return out\n}\n"],"names":[],"mappings":"AAiBgB,SAAA,OAAO,KAAU,KAAc;AACzC,MAAA,GACF,GACA,KACA,MAAM;AAER,OAAK,KAAK,KAAK;AACb,SAAK,MAAM,IAAI,CAAC,OAAO,QAAQ;AACzB,UAAA,MAAM,QAAQ,GAAG,GAAG;AACtB,aAAK,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AAC/B,kBAAQ,OAAO;AACf,iBAAO,mBAAmB,CAAC,IAAI,MAAM,mBAAmB,IAAI,CAAC,CAAC;AAAA,QAAA;AAAA,MAChE,OACK;AACL,gBAAQ,OAAO;AACf,eAAO,mBAAmB,CAAC,IAAI,MAAM,mBAAmB,GAAG;AAAA,MAAA;AAAA,IAC7D;AAAA,EACF;AAGF,UAAQ,OAAO,MAAM;AACvB;AAUA,SAAS,QAAQ,KAAU;AACrB,MAAA,CAAC,IAAY,QAAA;AACX,QAAA,MAAM,mBAAmB,GAAG;AAC9B,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,KAAc;AAC7C,MAAI,KAAK;AACT,QAAM,MAAW,CACf,GAAA,OAAO,MAAM,IAAI,OAAO,IAAI,MAAM,IAAI,KAAK,MAAM,GAAG;AAE9C,SAAA,MAAM,IAAI,SAAU;AACpB,UAAA,aAAa,IAAI,QAAQ,GAAG;AAClC,QAAI,eAAe,IAAI;AACjB,UAAA,IAAI,MAAM,GAAG,UAAU;AAC3B,UAAI,mBAAmB,CAAC;AACxB,YAAM,QAAQ,IAAI,MAAM,aAAa,CAAC;AAClC,UAAA,IAAI,CAAC,MAAM,QAAQ;AAEjB,YAAA,CAAC,IAAI,CAAA,EAAG,OAAO,IAAI,CAAC,GAAG,QAAQ,KAAK,CAAC;AAAA,MAAA,OACpC;AACD,YAAA,CAAC,IAAI,QAAQ,KAAK;AAAA,MAAA;AAAA,IACxB,OACK;AACD,UAAA;AACJ,UAAI,mBAAmB,CAAC;AACxB,UAAI,CAAC,IAAI;AAAA,IAAA;AAAA,EACX;AAGK,SAAA;AACT;"}
@@ -0,0 +1,2 @@
1
+ export declare const rootRouteId = "__root__";
2
+ export type RootRouteId = typeof rootRouteId;
@@ -0,0 +1,5 @@
1
+ const rootRouteId = "__root__";
2
+ export {
3
+ rootRouteId
4
+ };
5
+ //# sourceMappingURL=root.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"root.js","sources":["../../src/root.ts"],"sourcesContent":["export const rootRouteId = '__root__'\nexport type RootRouteId = typeof rootRouteId\n"],"names":[],"mappings":"AAAO,MAAM,cAAc;"}
@@ -0,0 +1,148 @@
1
+ import { ParsePathParams } from './link.js';
2
+ import { RootRouteId } from './root.js';
3
+ import { Assign } from './utils.js';
4
+ import { AnySchema, AnyStandardSchemaValidator, AnyValidatorAdapter, AnyValidatorObj, StandardSchemaValidator, ValidatorAdapter, ValidatorFn, ValidatorObj } from './validators.js';
5
+ export type AnyPathParams = {};
6
+ export type SearchSchemaInput = {
7
+ __TSearchSchemaInput__: 'TSearchSchemaInput';
8
+ };
9
+ export type AnyContext = {};
10
+ export interface RouteContext {
11
+ }
12
+ export type PreloadableObj = {
13
+ preload?: () => Promise<void>;
14
+ };
15
+ export type RoutePathOptions<TCustomId, TPath> = {
16
+ path: TPath;
17
+ } | {
18
+ id: TCustomId;
19
+ };
20
+ export interface StaticDataRouteOption {
21
+ }
22
+ export type RoutePathOptionsIntersection<TCustomId, TPath> = {
23
+ path: TPath;
24
+ id: TCustomId;
25
+ };
26
+ export type SearchFilter<TInput, TResult = TInput> = (prev: TInput) => TResult;
27
+ export type SearchMiddlewareContext<TSearchSchema> = {
28
+ search: TSearchSchema;
29
+ next: (newSearch: TSearchSchema) => TSearchSchema;
30
+ };
31
+ export type SearchMiddleware<TSearchSchema> = (ctx: SearchMiddlewareContext<TSearchSchema>) => TSearchSchema;
32
+ export type ResolveId<TParentRoute, TCustomId extends string, TPath extends string> = TParentRoute extends {
33
+ id: infer TParentId extends string;
34
+ } ? RoutePrefix<TParentId, string extends TCustomId ? TPath : TCustomId> : RootRouteId;
35
+ export type InferFullSearchSchema<TRoute> = TRoute extends {
36
+ types: {
37
+ fullSearchSchema: infer TFullSearchSchema;
38
+ };
39
+ } ? TFullSearchSchema : {};
40
+ export type InferFullSearchSchemaInput<TRoute> = TRoute extends {
41
+ types: {
42
+ fullSearchSchemaInput: infer TFullSearchSchemaInput;
43
+ };
44
+ } ? TFullSearchSchemaInput : {};
45
+ export type InferAllParams<TRoute> = TRoute extends {
46
+ types: {
47
+ allParams: infer TAllParams;
48
+ };
49
+ } ? TAllParams : {};
50
+ export type InferAllContext<TRoute> = unknown extends TRoute ? TRoute : TRoute extends {
51
+ types: {
52
+ allContext: infer TAllContext;
53
+ };
54
+ } ? TAllContext : {};
55
+ export type ResolveSearchSchemaFnInput<TSearchValidator> = TSearchValidator extends (input: infer TSearchSchemaInput) => any ? TSearchSchemaInput extends SearchSchemaInput ? Omit<TSearchSchemaInput, keyof SearchSchemaInput> : ResolveSearchSchemaFn<TSearchValidator> : AnySchema;
56
+ export type ResolveSearchSchemaInput<TSearchValidator> = TSearchValidator extends AnyStandardSchemaValidator ? NonNullable<TSearchValidator['~standard']['types']>['input'] : TSearchValidator extends AnyValidatorAdapter ? TSearchValidator['types']['input'] : TSearchValidator extends AnyValidatorObj ? ResolveSearchSchemaFnInput<TSearchValidator['parse']> : ResolveSearchSchemaFnInput<TSearchValidator>;
57
+ export type ResolveSearchSchemaFn<TSearchValidator> = TSearchValidator extends (...args: any) => infer TSearchSchema ? TSearchSchema : AnySchema;
58
+ export type ResolveSearchSchema<TSearchValidator> = unknown extends TSearchValidator ? TSearchValidator : TSearchValidator extends AnyStandardSchemaValidator ? NonNullable<TSearchValidator['~standard']['types']>['output'] : TSearchValidator extends AnyValidatorAdapter ? TSearchValidator['types']['output'] : TSearchValidator extends AnyValidatorObj ? ResolveSearchSchemaFn<TSearchValidator['parse']> : ResolveSearchSchemaFn<TSearchValidator>;
59
+ export type ParseSplatParams<TPath extends string> = TPath & `${string}$` extends never ? TPath & `${string}$/${string}` extends never ? never : '_splat' : '_splat';
60
+ export interface SplatParams {
61
+ _splat?: string;
62
+ }
63
+ export type ResolveParams<TPath extends string> = ParseSplatParams<TPath> extends never ? Record<ParsePathParams<TPath>, string> : Record<ParsePathParams<TPath>, string> & SplatParams;
64
+ export type ParseParamsFn<in out TPath extends string, in out TParams> = (rawParams: ResolveParams<TPath>) => TParams extends Record<ParsePathParams<TPath>, any> ? TParams : Record<ParsePathParams<TPath>, any>;
65
+ export type StringifyParamsFn<in out TPath extends string, in out TParams> = (params: TParams) => ResolveParams<TPath>;
66
+ export type ParamsOptions<in out TPath extends string, in out TParams> = {
67
+ params?: {
68
+ parse?: ParseParamsFn<TPath, TParams>;
69
+ stringify?: StringifyParamsFn<TPath, TParams>;
70
+ };
71
+ /**
72
+ @deprecated Use params.parse instead
73
+ */
74
+ parseParams?: ParseParamsFn<TPath, TParams>;
75
+ /**
76
+ @deprecated Use params.stringify instead
77
+ */
78
+ stringifyParams?: StringifyParamsFn<TPath, TParams>;
79
+ };
80
+ interface RequiredStaticDataRouteOption {
81
+ staticData: StaticDataRouteOption;
82
+ }
83
+ interface OptionalStaticDataRouteOption {
84
+ staticData?: StaticDataRouteOption;
85
+ }
86
+ export type UpdatableStaticRouteOption = {} extends StaticDataRouteOption ? OptionalStaticDataRouteOption : RequiredStaticDataRouteOption;
87
+ export type MetaDescriptor = {
88
+ charSet: 'utf-8';
89
+ } | {
90
+ title: string;
91
+ } | {
92
+ name: string;
93
+ content: string;
94
+ } | {
95
+ property: string;
96
+ content: string;
97
+ } | {
98
+ httpEquiv: string;
99
+ content: string;
100
+ } | {
101
+ 'script:ld+json': LdJsonObject;
102
+ } | {
103
+ tagName: 'meta' | 'link';
104
+ [name: string]: string;
105
+ } | Record<string, unknown>;
106
+ type LdJsonObject = {
107
+ [Key in string]: LdJsonValue;
108
+ } & {
109
+ [Key in string]?: LdJsonValue | undefined;
110
+ };
111
+ type LdJsonArray = Array<LdJsonValue> | ReadonlyArray<LdJsonValue>;
112
+ type LdJsonPrimitive = string | number | boolean | null;
113
+ type LdJsonValue = LdJsonPrimitive | LdJsonObject | LdJsonArray;
114
+ export type RouteLinkEntry = {};
115
+ export type SearchValidator<TInput, TOutput> = ValidatorObj<TInput, TOutput> | ValidatorFn<TInput, TOutput> | ValidatorAdapter<TInput, TOutput> | StandardSchemaValidator<TInput, TOutput> | undefined;
116
+ export type AnySearchValidator = SearchValidator<any, any>;
117
+ export type DefaultSearchValidator = SearchValidator<Record<string, unknown>, AnySchema>;
118
+ export type LooseReturnType<T> = T extends (...args: Array<any>) => infer TReturn ? TReturn : never;
119
+ export type LooseAsyncReturnType<T> = T extends (...args: Array<any>) => infer TReturn ? TReturn extends Promise<infer TReturn> ? TReturn : TReturn : never;
120
+ export type ContextReturnType<TContextFn> = unknown extends TContextFn ? TContextFn : LooseReturnType<TContextFn> extends never ? AnyContext : LooseReturnType<TContextFn>;
121
+ export type ContextAsyncReturnType<TContextFn> = unknown extends TContextFn ? TContextFn : LooseAsyncReturnType<TContextFn> extends never ? AnyContext : LooseAsyncReturnType<TContextFn>;
122
+ export type ResolveRouteContext<TRouteContextFn, TBeforeLoadFn> = Assign<ContextReturnType<TRouteContextFn>, ContextAsyncReturnType<TBeforeLoadFn>>;
123
+ export type ResolveLoaderData<TLoaderFn> = unknown extends TLoaderFn ? TLoaderFn : LooseAsyncReturnType<TLoaderFn> extends never ? {} : LooseAsyncReturnType<TLoaderFn>;
124
+ export type RoutePrefix<TPrefix extends string, TPath extends string> = string extends TPath ? RootRouteId : TPath extends string ? TPrefix extends RootRouteId ? TPath extends '/' ? '/' : `/${TrimPath<TPath>}` : `${TPrefix}/${TPath}` extends '/' ? '/' : `/${TrimPathLeft<`${TrimPathRight<TPrefix>}/${TrimPath<TPath>}`>}` : never;
125
+ export type TrimPath<T extends string> = '' extends T ? '' : TrimPathRight<TrimPathLeft<T>>;
126
+ export type TrimPathLeft<T extends string> = T extends `${RootRouteId}/${infer U}` ? TrimPathLeft<U> : T extends `/${infer U}` ? TrimPathLeft<U> : T;
127
+ export type TrimPathRight<T extends string> = T extends '/' ? '/' : T extends `${infer U}/` ? TrimPathRight<U> : T;
128
+ /**
129
+ * @deprecated Use `ErrorComponentProps` instead.
130
+ */
131
+ export type ErrorRouteProps = {
132
+ error: unknown;
133
+ info?: {
134
+ componentStack: string;
135
+ };
136
+ reset: () => void;
137
+ };
138
+ export type ErrorComponentProps = {
139
+ error: Error;
140
+ info?: {
141
+ componentStack: string;
142
+ };
143
+ reset: () => void;
144
+ };
145
+ export type NotFoundRouteProps = {
146
+ data: unknown;
147
+ };
148
+ export {};
@@ -0,0 +1,31 @@
1
+ import { DeferredPromiseState } from './defer.js';
2
+ import { ControlledPromise } from './utils.js';
3
+ export interface ViewTransitionOptions {
4
+ types: Array<string>;
5
+ }
6
+ export declare function defaultSerializeError(err: unknown): {
7
+ name: string;
8
+ message: string;
9
+ } | {
10
+ data: unknown;
11
+ };
12
+ export interface ExtractedBaseEntry {
13
+ dataType: '__beforeLoadContext' | 'loaderData';
14
+ type: string;
15
+ path: Array<string>;
16
+ id: number;
17
+ matchIndex: number;
18
+ }
19
+ export interface ExtractedStream extends ExtractedBaseEntry {
20
+ type: 'stream';
21
+ streamState: StreamState;
22
+ }
23
+ export interface ExtractedPromise extends ExtractedBaseEntry {
24
+ type: 'promise';
25
+ promiseState: DeferredPromiseState<any>;
26
+ }
27
+ export type ExtractedEntry = ExtractedStream | ExtractedPromise;
28
+ export type StreamState = {
29
+ promises: Array<ControlledPromise<string | null>>;
30
+ };
31
+ export type TrailingSlashOption = 'always' | 'never' | 'preserve';
@@ -0,0 +1,19 @@
1
+ function defaultSerializeError(err) {
2
+ if (err instanceof Error) {
3
+ const obj = {
4
+ name: err.name,
5
+ message: err.message
6
+ };
7
+ if (process.env.NODE_ENV === "development") {
8
+ obj.stack = err.stack;
9
+ }
10
+ return obj;
11
+ }
12
+ return {
13
+ data: err
14
+ };
15
+ }
16
+ export {
17
+ defaultSerializeError
18
+ };
19
+ //# sourceMappingURL=router.js.map