@tanstack/router-core 1.132.0-alpha.2 → 1.132.0-alpha.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Matches.cjs.map +1 -1
- package/dist/cjs/Matches.d.cts +2 -2
- package/dist/cjs/config.cjs +10 -0
- package/dist/cjs/config.cjs.map +1 -0
- package/dist/cjs/config.d.cts +17 -0
- package/dist/cjs/fileRoute.d.cts +3 -2
- package/dist/cjs/index.cjs +15 -3
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +11 -4
- package/dist/cjs/load-matches.cjs +636 -0
- package/dist/cjs/load-matches.cjs.map +1 -0
- package/dist/cjs/load-matches.d.cts +16 -0
- package/dist/cjs/location.d.cts +38 -0
- package/dist/cjs/path.cjs +7 -49
- package/dist/cjs/path.cjs.map +1 -1
- package/dist/cjs/path.d.cts +3 -6
- package/dist/cjs/qss.cjs +19 -19
- package/dist/cjs/qss.cjs.map +1 -1
- package/dist/cjs/qss.d.cts +6 -4
- package/dist/cjs/redirect.cjs +3 -3
- package/dist/cjs/redirect.cjs.map +1 -1
- package/dist/cjs/rewrite.cjs +63 -0
- package/dist/cjs/rewrite.cjs.map +1 -0
- package/dist/cjs/rewrite.d.cts +22 -0
- package/dist/cjs/route.cjs.map +1 -1
- package/dist/cjs/route.d.cts +42 -37
- package/dist/cjs/router.cjs +134 -780
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +68 -36
- package/dist/cjs/scroll-restoration.cjs +32 -29
- package/dist/cjs/scroll-restoration.cjs.map +1 -1
- package/dist/cjs/scroll-restoration.d.cts +1 -1
- package/dist/cjs/searchParams.cjs +7 -15
- package/dist/cjs/searchParams.cjs.map +1 -1
- package/dist/cjs/ssr/constants.cjs +5 -0
- package/dist/cjs/ssr/constants.cjs.map +1 -0
- package/dist/cjs/ssr/constants.d.cts +1 -0
- package/dist/cjs/ssr/{seroval-plugins.cjs → serializer/ShallowErrorPlugin.cjs} +2 -2
- package/dist/cjs/ssr/serializer/ShallowErrorPlugin.cjs.map +1 -0
- package/dist/cjs/ssr/{seroval-plugins.d.cts → serializer/ShallowErrorPlugin.d.cts} +1 -2
- package/dist/cjs/ssr/serializer/seroval-plugins.cjs +11 -0
- package/dist/cjs/ssr/serializer/seroval-plugins.cjs.map +1 -0
- package/dist/cjs/ssr/serializer/seroval-plugins.d.cts +2 -0
- package/dist/cjs/ssr/serializer/transformer.cjs +52 -0
- package/dist/cjs/ssr/serializer/transformer.cjs.map +1 -0
- package/dist/cjs/ssr/serializer/transformer.d.cts +56 -0
- package/dist/cjs/ssr/server.d.cts +5 -0
- package/dist/cjs/ssr/ssr-client.cjs +15 -1
- package/dist/cjs/ssr/ssr-client.cjs.map +1 -1
- package/dist/cjs/ssr/ssr-client.d.cts +5 -1
- package/dist/cjs/ssr/ssr-server.cjs +12 -10
- package/dist/cjs/ssr/ssr-server.cjs.map +1 -1
- package/dist/cjs/ssr/ssr-server.d.cts +0 -1
- package/dist/cjs/ssr/tsrScript.cjs +1 -1
- package/dist/cjs/ssr/tsrScript.cjs.map +1 -1
- package/dist/cjs/utils.cjs +8 -7
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +1 -1
- package/dist/esm/Matches.d.ts +2 -2
- package/dist/esm/Matches.js.map +1 -1
- package/dist/esm/config.d.ts +17 -0
- package/dist/esm/config.js +10 -0
- package/dist/esm/config.js.map +1 -0
- package/dist/esm/fileRoute.d.ts +3 -2
- package/dist/esm/index.d.ts +11 -4
- package/dist/esm/index.js +17 -5
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/load-matches.d.ts +16 -0
- package/dist/esm/load-matches.js +636 -0
- package/dist/esm/load-matches.js.map +1 -0
- package/dist/esm/location.d.ts +38 -0
- package/dist/esm/path.d.ts +3 -6
- package/dist/esm/path.js +7 -49
- package/dist/esm/path.js.map +1 -1
- package/dist/esm/qss.d.ts +6 -4
- package/dist/esm/qss.js +19 -19
- package/dist/esm/qss.js.map +1 -1
- package/dist/esm/redirect.js +3 -3
- package/dist/esm/redirect.js.map +1 -1
- package/dist/esm/rewrite.d.ts +22 -0
- package/dist/esm/rewrite.js +63 -0
- package/dist/esm/rewrite.js.map +1 -0
- package/dist/esm/route.d.ts +42 -37
- package/dist/esm/route.js.map +1 -1
- package/dist/esm/router.d.ts +68 -36
- package/dist/esm/router.js +136 -782
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/scroll-restoration.d.ts +1 -1
- package/dist/esm/scroll-restoration.js +32 -29
- package/dist/esm/scroll-restoration.js.map +1 -1
- package/dist/esm/searchParams.js +7 -15
- package/dist/esm/searchParams.js.map +1 -1
- package/dist/esm/ssr/constants.d.ts +1 -0
- package/dist/esm/ssr/constants.js +5 -0
- package/dist/esm/ssr/constants.js.map +1 -0
- package/dist/esm/ssr/{seroval-plugins.d.ts → serializer/ShallowErrorPlugin.d.ts} +1 -2
- package/dist/esm/ssr/{seroval-plugins.js → serializer/ShallowErrorPlugin.js} +2 -2
- package/dist/esm/ssr/serializer/ShallowErrorPlugin.js.map +1 -0
- package/dist/esm/ssr/serializer/seroval-plugins.d.ts +2 -0
- package/dist/esm/ssr/serializer/seroval-plugins.js +11 -0
- package/dist/esm/ssr/serializer/seroval-plugins.js.map +1 -0
- package/dist/esm/ssr/serializer/transformer.d.ts +56 -0
- package/dist/esm/ssr/serializer/transformer.js +52 -0
- package/dist/esm/ssr/serializer/transformer.js.map +1 -0
- package/dist/esm/ssr/server.d.ts +5 -0
- package/dist/esm/ssr/ssr-client.d.ts +5 -1
- package/dist/esm/ssr/ssr-client.js +15 -1
- package/dist/esm/ssr/ssr-client.js.map +1 -1
- package/dist/esm/ssr/ssr-server.d.ts +0 -1
- package/dist/esm/ssr/ssr-server.js +12 -10
- package/dist/esm/ssr/ssr-server.js.map +1 -1
- package/dist/esm/ssr/tsrScript.js +1 -1
- package/dist/esm/ssr/tsrScript.js.map +1 -1
- package/dist/esm/utils.d.ts +1 -1
- package/dist/esm/utils.js +8 -7
- package/dist/esm/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/Matches.ts +2 -2
- package/src/config.ts +42 -0
- package/src/fileRoute.ts +15 -3
- package/src/index.ts +32 -3
- package/src/load-matches.ts +955 -0
- package/src/location.ts +38 -0
- package/src/path.ts +9 -66
- package/src/qss.ts +27 -24
- package/src/redirect.ts +3 -3
- package/src/rewrite.ts +70 -0
- package/src/route.ts +136 -33
- package/src/router.ts +271 -1170
- package/src/scroll-restoration.ts +42 -37
- package/src/searchParams.ts +8 -19
- package/src/ssr/constants.ts +1 -0
- package/src/ssr/{seroval-plugins.ts → serializer/ShallowErrorPlugin.ts} +2 -2
- package/src/ssr/serializer/seroval-plugins.ts +9 -0
- package/src/ssr/serializer/transformer.ts +215 -0
- package/src/ssr/server.ts +6 -0
- package/src/ssr/ssr-client.ts +30 -3
- package/src/ssr/ssr-server.ts +18 -10
- package/src/ssr/tsrScript.ts +5 -1
- package/src/utils.ts +11 -10
- package/dist/cjs/ssr/seroval-plugins.cjs.map +0 -1
- package/dist/esm/ssr/seroval-plugins.js.map +0 -1
package/src/location.ts
CHANGED
|
@@ -2,12 +2,50 @@ import type { ParsedHistoryState } from '@tanstack/history'
|
|
|
2
2
|
import type { AnySchema } from './validators'
|
|
3
3
|
|
|
4
4
|
export interface ParsedLocation<TSearchObj extends AnySchema = {}> {
|
|
5
|
+
/**
|
|
6
|
+
* The full path of the location, including pathname, search, and hash.
|
|
7
|
+
* Does not include the origin. Is the equivalent of calling
|
|
8
|
+
* `url.replace(url.origin, '')`
|
|
9
|
+
*/
|
|
5
10
|
href: string
|
|
11
|
+
/**
|
|
12
|
+
* @description The pathname of the location, including the leading slash.
|
|
13
|
+
*/
|
|
6
14
|
pathname: string
|
|
15
|
+
/**
|
|
16
|
+
* The parsed search parameters of the location in object form.
|
|
17
|
+
*/
|
|
7
18
|
search: TSearchObj
|
|
19
|
+
/**
|
|
20
|
+
* The search string of the location, including the leading question mark.
|
|
21
|
+
*/
|
|
8
22
|
searchStr: string
|
|
23
|
+
/**
|
|
24
|
+
* The in-memory state of the location as it *may* exist in the browser's history.
|
|
25
|
+
*/
|
|
9
26
|
state: ParsedHistoryState
|
|
27
|
+
/**
|
|
28
|
+
* The hash of the location, including the leading hash character.
|
|
29
|
+
*/
|
|
10
30
|
hash: string
|
|
31
|
+
/**
|
|
32
|
+
* The masked location of the location.
|
|
33
|
+
*/
|
|
11
34
|
maskedLocation?: ParsedLocation<TSearchObj>
|
|
35
|
+
/**
|
|
36
|
+
* Whether to unmask the location on reload.
|
|
37
|
+
*/
|
|
12
38
|
unmaskOnReload?: boolean
|
|
39
|
+
/**
|
|
40
|
+
* @private
|
|
41
|
+
* @description The public href of the location, including the origin before any rewrites.
|
|
42
|
+
* If a rewrite is applied, the `href` property will be the rewritten URL.
|
|
43
|
+
*/
|
|
44
|
+
publicHref: string
|
|
45
|
+
/**
|
|
46
|
+
* @private
|
|
47
|
+
* @description The full URL of the location, including the origin.
|
|
48
|
+
* @private
|
|
49
|
+
*/
|
|
50
|
+
url: string
|
|
13
51
|
}
|
package/src/path.ts
CHANGED
|
@@ -97,11 +97,9 @@ export function exactPathTest(
|
|
|
97
97
|
// /a/b/c + d/ = /a/b/c/d
|
|
98
98
|
// /a/b/c + d/e = /a/b/c/d/e
|
|
99
99
|
interface ResolvePathOptions {
|
|
100
|
-
basepath: string
|
|
101
100
|
base: string
|
|
102
101
|
to: string
|
|
103
102
|
trailingSlash?: 'always' | 'never' | 'preserve'
|
|
104
|
-
caseSensitive?: boolean
|
|
105
103
|
parseCache?: ParsePathnameCache
|
|
106
104
|
}
|
|
107
105
|
|
|
@@ -151,16 +149,11 @@ function segmentToString(segment: Segment): string {
|
|
|
151
149
|
}
|
|
152
150
|
|
|
153
151
|
export function resolvePath({
|
|
154
|
-
basepath,
|
|
155
152
|
base,
|
|
156
153
|
to,
|
|
157
154
|
trailingSlash = 'never',
|
|
158
|
-
caseSensitive,
|
|
159
155
|
parseCache,
|
|
160
156
|
}: ResolvePathOptions) {
|
|
161
|
-
base = removeBasepath(basepath, base, caseSensitive)
|
|
162
|
-
to = removeBasepath(basepath, to, caseSensitive)
|
|
163
|
-
|
|
164
157
|
let baseSegments = parsePathname(base, parseCache).slice()
|
|
165
158
|
const toSegments = parsePathname(to, parseCache)
|
|
166
159
|
|
|
@@ -201,7 +194,8 @@ export function resolvePath({
|
|
|
201
194
|
}
|
|
202
195
|
|
|
203
196
|
const segmentValues = baseSegments.map(segmentToString)
|
|
204
|
-
const joined = joinPaths([basepath, ...segmentValues])
|
|
197
|
+
// const joined = joinPaths([basepath, ...segmentValues])
|
|
198
|
+
const joined = joinPaths(segmentValues)
|
|
205
199
|
return joined
|
|
206
200
|
}
|
|
207
201
|
|
|
@@ -403,6 +397,10 @@ export function interpolatePath({
|
|
|
403
397
|
|
|
404
398
|
if (segment.type === SEGMENT_TYPE_WILDCARD) {
|
|
405
399
|
usedParams._splat = params._splat
|
|
400
|
+
|
|
401
|
+
// TODO: Deprecate *
|
|
402
|
+
usedParams['*'] = params._splat
|
|
403
|
+
|
|
406
404
|
const segmentPrefix = segment.prefixSegment || ''
|
|
407
405
|
const segmentSuffix = segment.suffixSegment || ''
|
|
408
406
|
|
|
@@ -491,17 +489,11 @@ function encodePathParam(value: string, decodeCharMap?: Map<string, string>) {
|
|
|
491
489
|
}
|
|
492
490
|
|
|
493
491
|
export function matchPathname(
|
|
494
|
-
basepath: string,
|
|
495
492
|
currentPathname: string,
|
|
496
493
|
matchLocation: Pick<MatchLocation, 'to' | 'fuzzy' | 'caseSensitive'>,
|
|
497
494
|
parseCache?: ParsePathnameCache,
|
|
498
495
|
): AnyPathParams | undefined {
|
|
499
|
-
const pathParams = matchByPath(
|
|
500
|
-
basepath,
|
|
501
|
-
currentPathname,
|
|
502
|
-
matchLocation,
|
|
503
|
-
parseCache,
|
|
504
|
-
)
|
|
496
|
+
const pathParams = matchByPath(currentPathname, matchLocation, parseCache)
|
|
505
497
|
// const searchMatched = matchBySearch(location.search, matchLocation)
|
|
506
498
|
|
|
507
499
|
if (matchLocation.to && !pathParams) {
|
|
@@ -511,49 +503,7 @@ export function matchPathname(
|
|
|
511
503
|
return pathParams ?? {}
|
|
512
504
|
}
|
|
513
505
|
|
|
514
|
-
export function removeBasepath(
|
|
515
|
-
basepath: string,
|
|
516
|
-
pathname: string,
|
|
517
|
-
caseSensitive: boolean = false,
|
|
518
|
-
) {
|
|
519
|
-
// normalize basepath and pathname for case-insensitive comparison if needed
|
|
520
|
-
const normalizedBasepath = caseSensitive ? basepath : basepath.toLowerCase()
|
|
521
|
-
const normalizedPathname = caseSensitive ? pathname : pathname.toLowerCase()
|
|
522
|
-
|
|
523
|
-
switch (true) {
|
|
524
|
-
// default behaviour is to serve app from the root - pathname
|
|
525
|
-
// left untouched
|
|
526
|
-
case normalizedBasepath === '/':
|
|
527
|
-
return pathname
|
|
528
|
-
|
|
529
|
-
// shortcut for removing the basepath if it matches the pathname
|
|
530
|
-
case normalizedPathname === normalizedBasepath:
|
|
531
|
-
return ''
|
|
532
|
-
|
|
533
|
-
// in case pathname is shorter than basepath - there is
|
|
534
|
-
// nothing to remove
|
|
535
|
-
case pathname.length < basepath.length:
|
|
536
|
-
return pathname
|
|
537
|
-
|
|
538
|
-
// avoid matching partial segments - strict equality handled
|
|
539
|
-
// earlier, otherwise, basepath separated from pathname with
|
|
540
|
-
// separator, therefore lack of separator means partial
|
|
541
|
-
// segment match (`/app` should not match `/application`)
|
|
542
|
-
case normalizedPathname[normalizedBasepath.length] !== '/':
|
|
543
|
-
return pathname
|
|
544
|
-
|
|
545
|
-
// remove the basepath from the pathname if it starts with it
|
|
546
|
-
case normalizedPathname.startsWith(normalizedBasepath):
|
|
547
|
-
return pathname.slice(basepath.length)
|
|
548
|
-
|
|
549
|
-
// otherwise, return the pathname as is
|
|
550
|
-
default:
|
|
551
|
-
return pathname
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
|
|
555
506
|
export function matchByPath(
|
|
556
|
-
basepath: string,
|
|
557
507
|
from: string,
|
|
558
508
|
{
|
|
559
509
|
to,
|
|
@@ -562,14 +512,7 @@ export function matchByPath(
|
|
|
562
512
|
}: Pick<MatchLocation, 'to' | 'caseSensitive' | 'fuzzy'>,
|
|
563
513
|
parseCache?: ParsePathnameCache,
|
|
564
514
|
): Record<string, string> | undefined {
|
|
565
|
-
|
|
566
|
-
if (basepath !== '/' && !from.startsWith(basepath)) {
|
|
567
|
-
return undefined
|
|
568
|
-
}
|
|
569
|
-
// Remove the base path from the pathname
|
|
570
|
-
from = removeBasepath(basepath, from, caseSensitive)
|
|
571
|
-
// Default to to $ (wildcard)
|
|
572
|
-
to = removeBasepath(basepath, `${to ?? '$'}`, caseSensitive)
|
|
515
|
+
const stringTo = to as string
|
|
573
516
|
|
|
574
517
|
// Parse the from and to
|
|
575
518
|
const baseSegments = parsePathname(
|
|
@@ -577,7 +520,7 @@ export function matchByPath(
|
|
|
577
520
|
parseCache,
|
|
578
521
|
)
|
|
579
522
|
const routeSegments = parsePathname(
|
|
580
|
-
|
|
523
|
+
stringTo.startsWith('/') ? stringTo : `/${stringTo}`,
|
|
581
524
|
parseCache,
|
|
582
525
|
)
|
|
583
526
|
|
package/src/qss.ts
CHANGED
|
@@ -6,12 +6,15 @@
|
|
|
6
6
|
* This reimplementation uses modern browser APIs
|
|
7
7
|
* (namely URLSearchParams) and TypeScript while still
|
|
8
8
|
* maintaining the original functionality and interface.
|
|
9
|
+
*
|
|
10
|
+
* Update: this implementation has also been mangled to
|
|
11
|
+
* fit exactly our use-case (single value per key in encoding).
|
|
9
12
|
*/
|
|
10
13
|
|
|
11
14
|
/**
|
|
12
15
|
* Encodes an object into a query string.
|
|
13
16
|
* @param obj - The object to encode into a query string.
|
|
14
|
-
* @param
|
|
17
|
+
* @param stringify - An optional custom stringify function.
|
|
15
18
|
* @returns The encoded query string.
|
|
16
19
|
* @example
|
|
17
20
|
* ```
|
|
@@ -19,18 +22,20 @@
|
|
|
19
22
|
* // Expected output: "token=foo&key=value"
|
|
20
23
|
* ```
|
|
21
24
|
*/
|
|
22
|
-
export function encode(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return [[key, String(value)]]
|
|
28
|
-
}
|
|
29
|
-
})
|
|
25
|
+
export function encode(
|
|
26
|
+
obj: Record<string, any>,
|
|
27
|
+
stringify: (value: any) => string = String,
|
|
28
|
+
): string {
|
|
29
|
+
const result = new URLSearchParams()
|
|
30
30
|
|
|
31
|
-
const
|
|
31
|
+
for (const key in obj) {
|
|
32
|
+
const val = obj[key]
|
|
33
|
+
if (val !== undefined) {
|
|
34
|
+
result.set(key, stringify(val))
|
|
35
|
+
}
|
|
36
|
+
}
|
|
32
37
|
|
|
33
|
-
return
|
|
38
|
+
return result.toString()
|
|
34
39
|
}
|
|
35
40
|
|
|
36
41
|
/**
|
|
@@ -52,28 +57,26 @@ function toValue(str: unknown) {
|
|
|
52
57
|
/**
|
|
53
58
|
* Decodes a query string into an object.
|
|
54
59
|
* @param str - The query string to decode.
|
|
55
|
-
* @param [pfx] - An optional prefix to filter out from the query string.
|
|
56
60
|
* @returns The decoded key-value pairs in an object format.
|
|
57
61
|
* @example
|
|
58
62
|
* // Example input: decode("token=foo&key=value")
|
|
59
63
|
* // Expected output: { "token": "foo", "key": "value" }
|
|
60
64
|
*/
|
|
61
|
-
export function decode(str: any
|
|
62
|
-
const
|
|
63
|
-
const searchParams = new URLSearchParams(searchParamsPart)
|
|
65
|
+
export function decode(str: any): any {
|
|
66
|
+
const searchParams = new URLSearchParams(str)
|
|
64
67
|
|
|
65
|
-
const
|
|
68
|
+
const result: Record<string, unknown> = {}
|
|
66
69
|
|
|
67
|
-
|
|
68
|
-
const previousValue =
|
|
70
|
+
for (const [key, value] of searchParams.entries()) {
|
|
71
|
+
const previousValue = result[key]
|
|
69
72
|
if (previousValue == null) {
|
|
70
|
-
|
|
73
|
+
result[key] = toValue(value)
|
|
74
|
+
} else if (Array.isArray(previousValue)) {
|
|
75
|
+
previousValue.push(toValue(value))
|
|
71
76
|
} else {
|
|
72
|
-
|
|
73
|
-
? [...previousValue, toValue(value)]
|
|
74
|
-
: [previousValue, toValue(value)]
|
|
77
|
+
result[key] = [previousValue, toValue(value)]
|
|
75
78
|
}
|
|
79
|
+
}
|
|
76
80
|
|
|
77
|
-
|
|
78
|
-
}, {})
|
|
81
|
+
return result
|
|
79
82
|
}
|
package/src/redirect.ts
CHANGED
|
@@ -65,9 +65,9 @@ export function redirect<
|
|
|
65
65
|
): Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> {
|
|
66
66
|
opts.statusCode = opts.statusCode || opts.code || 307
|
|
67
67
|
|
|
68
|
-
if (!opts.reloadDocument) {
|
|
68
|
+
if (!opts.reloadDocument && typeof opts.href === 'string') {
|
|
69
69
|
try {
|
|
70
|
-
new URL(
|
|
70
|
+
new URL(opts.href)
|
|
71
71
|
opts.reloadDocument = true
|
|
72
72
|
} catch {}
|
|
73
73
|
}
|
|
@@ -103,7 +103,7 @@ export function isResolvedRedirect(
|
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
export function parseRedirect(obj: any) {
|
|
106
|
-
if (typeof obj === 'object' && obj.isSerializedRedirect) {
|
|
106
|
+
if (obj !== null && typeof obj === 'object' && obj.isSerializedRedirect) {
|
|
107
107
|
return redirect(obj)
|
|
108
108
|
}
|
|
109
109
|
|
package/src/rewrite.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { joinPaths, trimPath } from './path'
|
|
2
|
+
import type { LocationRewrite } from './router'
|
|
3
|
+
|
|
4
|
+
export function composeRewrites(rewrites: Array<LocationRewrite>) {
|
|
5
|
+
return {
|
|
6
|
+
input: ({ url }) => {
|
|
7
|
+
for (const rewrite of rewrites) {
|
|
8
|
+
url = executeRewriteInput(rewrite, url)
|
|
9
|
+
}
|
|
10
|
+
return url
|
|
11
|
+
},
|
|
12
|
+
output: ({ url }) => {
|
|
13
|
+
for (let i = rewrites.length - 1; i >= 0; i--) {
|
|
14
|
+
url = executeRewriteOutput(rewrites[i], url)
|
|
15
|
+
}
|
|
16
|
+
return url
|
|
17
|
+
},
|
|
18
|
+
} satisfies LocationRewrite
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function rewriteBasepath(opts: {
|
|
22
|
+
basepath: string
|
|
23
|
+
caseSensitive?: boolean
|
|
24
|
+
}) {
|
|
25
|
+
const trimmedBasepath = trimPath(opts.basepath)
|
|
26
|
+
const regex = new RegExp(
|
|
27
|
+
`^/${trimmedBasepath}/`,
|
|
28
|
+
opts.caseSensitive ? '' : 'i',
|
|
29
|
+
)
|
|
30
|
+
return {
|
|
31
|
+
input: ({ url }) => {
|
|
32
|
+
url.pathname = url.pathname.replace(regex, '/')
|
|
33
|
+
return url
|
|
34
|
+
},
|
|
35
|
+
output: ({ url }) => {
|
|
36
|
+
url.pathname = joinPaths(['/', trimmedBasepath, url.pathname])
|
|
37
|
+
return url
|
|
38
|
+
},
|
|
39
|
+
} satisfies LocationRewrite
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function executeRewriteInput(
|
|
43
|
+
rewrite: LocationRewrite | undefined,
|
|
44
|
+
url: URL,
|
|
45
|
+
): URL {
|
|
46
|
+
const res = rewrite?.input?.({ url })
|
|
47
|
+
if (res) {
|
|
48
|
+
if (typeof res === 'string') {
|
|
49
|
+
return new URL(res)
|
|
50
|
+
} else if (res instanceof URL) {
|
|
51
|
+
return res
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return url
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function executeRewriteOutput(
|
|
58
|
+
rewrite: LocationRewrite | undefined,
|
|
59
|
+
url: URL,
|
|
60
|
+
): URL {
|
|
61
|
+
const res = rewrite?.output?.({ url })
|
|
62
|
+
if (res) {
|
|
63
|
+
if (typeof res === 'string') {
|
|
64
|
+
return new URL(res)
|
|
65
|
+
} else if (res instanceof URL) {
|
|
66
|
+
return res
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return url
|
|
70
|
+
}
|