Skip to content

Commit ac6c3cb

Browse files
committed
Merge branch 'master' into version-2
2 parents 8a80190 + d7eb990 commit ac6c3cb

File tree

7 files changed

+96
-0
lines changed

7 files changed

+96
-0
lines changed

.changeset/nervous-mails-tickle.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/kit': minor
3+
---
4+
5+
feat: add `resolveRoute` to `$app/paths`, deprecate `resolvePath`

packages/kit/src/exports/index.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,11 @@ export function fail(status, data) {
186186

187187
const basic_param_pattern = /\[(\[)?(\.\.\.)?(\w+?)(?:=(\w+))?\]\]?/g;
188188

189+
let warned = false;
190+
189191
/**
192+
* @deprecated Use `resolveRoute` from `$app/paths` instead.
193+
*
190194
* Populate a route ID with params to resolve a pathname.
191195
* @example
192196
* ```js
@@ -203,6 +207,11 @@ const basic_param_pattern = /\[(\[)?(\.\.\.)?(\w+?)(?:=(\w+))?\]\]?/g;
203207
* @returns {string}
204208
*/
205209
export function resolvePath(id, params) {
210+
if (!warned) {
211+
console.warn('`resolvePath` is deprecated. Use `resolveRoute` from `$app/paths` instead.');
212+
warned = true;
213+
}
214+
206215
const segments = get_route_segments(id);
207216
return (
208217
'/' +

packages/kit/src/runtime/app/paths.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,50 @@
11
export { base, assets } from '__sveltekit/paths';
2+
import { base } from '__sveltekit/paths';
3+
import { get_route_segments } from '../../utils/routing.js';
4+
5+
const basic_param_pattern = /\[(\[)?(\.\.\.)?(\w+?)(?:=(\w+))?\]\]?/g;
6+
7+
/**
8+
* Populate a route ID with params to resolve a pathname.
9+
* @example
10+
* ```js
11+
* resolveRoute(
12+
* `/blog/[slug]/[...somethingElse]`,
13+
* {
14+
* slug: 'hello-world',
15+
* somethingElse: 'something/else'
16+
* }
17+
* ); // `/blog/hello-world/something/else`
18+
* ```
19+
* @param {string} id
20+
* @param {Record<string, string | undefined>} params
21+
* @returns {string}
22+
*/
23+
export function resolveRoute(id, params) {
24+
const segments = get_route_segments(id);
25+
return (
26+
base +
27+
'/' +
28+
segments
29+
.map((segment) =>
30+
segment.replace(basic_param_pattern, (_, optional, rest, name) => {
31+
const param_value = params[name];
32+
33+
// This is nested so TS correctly narrows the type
34+
if (!param_value) {
35+
if (optional) return '';
36+
if (rest && param_value !== undefined) return '';
37+
throw new Error(`Missing parameter '${name}' in route ${id}`);
38+
}
39+
40+
if (param_value.startsWith('/') || param_value.endsWith('/'))
41+
throw new Error(
42+
`Parameter '${name}' in route ${id} cannot start or end with a slash -- this would cause an invalid route like foo//bar`
43+
);
44+
return param_value;
45+
})
46+
)
47+
.filter(Boolean)
48+
.join('/')
49+
);
50+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
import { resolveRoute } from '$app/paths';
3+
</script>
4+
5+
<a data-id="target" href={resolveRoute('/resolve-route/[foo]', { foo: 'resolved' })}>click me</a>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
import { page } from '$app/stores';
3+
</script>
4+
5+
<h2>{$page.params.foo}</h2>

packages/kit/test/apps/options/test/test.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,13 @@ test.describe('base path', () => {
9292
await clicknav('[href="/path-base/base/two"]');
9393
expect(await page.textContent('h2')).toBe('two');
9494
});
95+
96+
test('resolveRoute accounts for base path', async ({ baseURL, page, clicknav }) => {
97+
await page.goto('/path-base/resolve-route');
98+
await clicknav('[data-id=target]');
99+
expect(page.url()).toBe(`${baseURL}/path-base/resolve-route/resolved/`);
100+
expect(await page.textContent('h2')).toBe('resolved');
101+
});
95102
});
96103

97104
test.describe('assets path', () => {

packages/kit/types/index.d.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1737,6 +1737,8 @@ declare module '@sveltejs/kit' {
17371737
* */
17381738
export function fail<T extends Record<string, unknown> | undefined = undefined>(status: number, data: T): ActionFailure<T>;
17391739
/**
1740+
* @deprecated Use `resolveRoute` from `$app/paths` instead.
1741+
*
17401742
* Populate a route ID with params to resolve a pathname.
17411743
* @example
17421744
* ```js
@@ -2026,6 +2028,20 @@ declare module '$app/navigation' {
20262028

20272029
declare module '$app/paths' {
20282030
export { base, assets } from '__sveltekit/paths';
2031+
/**
2032+
* Populate a route ID with params to resolve a pathname.
2033+
* @example
2034+
* ```js
2035+
* resolveRoute(
2036+
* `/blog/[slug]/[...somethingElse]`,
2037+
* {
2038+
* slug: 'hello-world',
2039+
* somethingElse: 'something/else'
2040+
* }
2041+
* ); // `/blog/hello-world/something/else`
2042+
* ```
2043+
* */
2044+
export function resolveRoute(id: string, params: Record<string, string | undefined>): string;
20292045
}
20302046

20312047
declare module '$app/stores' {

0 commit comments

Comments
 (0)