@tanstack/router-core 1.132.0-alpha.1 → 1.132.0-alpha.15
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 +9 -11
- 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 +6 -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 -41
- package/dist/cjs/router.cjs +134 -681
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +68 -25
- 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 -10
- 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 +53 -40
- 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/typePrimitives.d.cts +6 -6
- package/dist/cjs/utils.cjs +14 -7
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +2 -1
- package/dist/esm/Matches.d.ts +9 -11
- 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 +6 -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 -41
- package/dist/esm/route.js.map +1 -1
- package/dist/esm/router.d.ts +68 -25
- package/dist/esm/router.js +136 -683
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/scroll-restoration.d.ts +1 -10
- 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 +53 -40
- 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/typePrimitives.d.ts +6 -6
- package/dist/esm/utils.d.ts +2 -1
- package/dist/esm/utils.js +14 -7
- package/dist/esm/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/Matches.ts +18 -10
- 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 +5 -66
- package/src/qss.ts +27 -24
- package/src/redirect.ts +3 -3
- package/src/rewrite.ts +70 -0
- package/src/route.ts +146 -35
- package/src/router.ts +263 -972
- 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 +72 -44
- package/src/ssr/ssr-server.ts +18 -10
- package/src/ssr/tsrScript.ts +5 -1
- package/src/typePrimitives.ts +6 -6
- package/src/utils.ts +21 -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
|
|
|
@@ -491,17 +485,11 @@ function encodePathParam(value: string, decodeCharMap?: Map<string, string>) {
|
|
|
491
485
|
}
|
|
492
486
|
|
|
493
487
|
export function matchPathname(
|
|
494
|
-
basepath: string,
|
|
495
488
|
currentPathname: string,
|
|
496
489
|
matchLocation: Pick<MatchLocation, 'to' | 'fuzzy' | 'caseSensitive'>,
|
|
497
490
|
parseCache?: ParsePathnameCache,
|
|
498
491
|
): AnyPathParams | undefined {
|
|
499
|
-
const pathParams = matchByPath(
|
|
500
|
-
basepath,
|
|
501
|
-
currentPathname,
|
|
502
|
-
matchLocation,
|
|
503
|
-
parseCache,
|
|
504
|
-
)
|
|
492
|
+
const pathParams = matchByPath(currentPathname, matchLocation, parseCache)
|
|
505
493
|
// const searchMatched = matchBySearch(location.search, matchLocation)
|
|
506
494
|
|
|
507
495
|
if (matchLocation.to && !pathParams) {
|
|
@@ -511,49 +499,7 @@ export function matchPathname(
|
|
|
511
499
|
return pathParams ?? {}
|
|
512
500
|
}
|
|
513
501
|
|
|
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
502
|
export function matchByPath(
|
|
556
|
-
basepath: string,
|
|
557
503
|
from: string,
|
|
558
504
|
{
|
|
559
505
|
to,
|
|
@@ -562,14 +508,7 @@ export function matchByPath(
|
|
|
562
508
|
}: Pick<MatchLocation, 'to' | 'caseSensitive' | 'fuzzy'>,
|
|
563
509
|
parseCache?: ParsePathnameCache,
|
|
564
510
|
): 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)
|
|
511
|
+
const stringTo = to as string
|
|
573
512
|
|
|
574
513
|
// Parse the from and to
|
|
575
514
|
const baseSegments = parsePathname(
|
|
@@ -577,7 +516,7 @@ export function matchByPath(
|
|
|
577
516
|
parseCache,
|
|
578
517
|
)
|
|
579
518
|
const routeSegments = parsePathname(
|
|
580
|
-
|
|
519
|
+
stringTo.startsWith('/') ? stringTo : `/${stringTo}`,
|
|
581
520
|
parseCache,
|
|
582
521
|
)
|
|
583
522
|
|
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
|
+
}
|