Skip to content

Commit

Permalink
Merge branch 'master' into version-2
Browse files Browse the repository at this point in the history
  • Loading branch information
Rich-Harris committed Dec 11, 2023
2 parents 8a80190 + d7eb990 commit ac6c3cb
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/nervous-mails-tickle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': minor
---

feat: add `resolveRoute` to `$app/paths`, deprecate `resolvePath`
9 changes: 9 additions & 0 deletions packages/kit/src/exports/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,11 @@ export function fail(status, data) {

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

let warned = false;

/**
* @deprecated Use `resolveRoute` from `$app/paths` instead.
*
* Populate a route ID with params to resolve a pathname.
* @example
* ```js
Expand All @@ -203,6 +207,11 @@ const basic_param_pattern = /\[(\[)?(\.\.\.)?(\w+?)(?:=(\w+))?\]\]?/g;
* @returns {string}
*/
export function resolvePath(id, params) {
if (!warned) {
console.warn('`resolvePath` is deprecated. Use `resolveRoute` from `$app/paths` instead.');
warned = true;
}

const segments = get_route_segments(id);
return (
'/' +
Expand Down
49 changes: 49 additions & 0 deletions packages/kit/src/runtime/app/paths.js
Original file line number Diff line number Diff line change
@@ -1 +1,50 @@
export { base, assets } from '__sveltekit/paths';
import { base } from '__sveltekit/paths';
import { get_route_segments } from '../../utils/routing.js';

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

/**
* Populate a route ID with params to resolve a pathname.
* @example
* ```js
* resolveRoute(
* `/blog/[slug]/[...somethingElse]`,
* {
* slug: 'hello-world',
* somethingElse: 'something/else'
* }
* ); // `/blog/hello-world/something/else`
* ```
* @param {string} id
* @param {Record<string, string | undefined>} params
* @returns {string}
*/
export function resolveRoute(id, params) {
const segments = get_route_segments(id);
return (
base +
'/' +
segments
.map((segment) =>
segment.replace(basic_param_pattern, (_, optional, rest, name) => {
const param_value = params[name];

// This is nested so TS correctly narrows the type
if (!param_value) {
if (optional) return '';
if (rest && param_value !== undefined) return '';
throw new Error(`Missing parameter '${name}' in route ${id}`);
}

if (param_value.startsWith('/') || param_value.endsWith('/'))
throw new Error(
`Parameter '${name}' in route ${id} cannot start or end with a slash -- this would cause an invalid route like foo//bar`
);
return param_value;
})
)
.filter(Boolean)
.join('/')
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<script>
import { resolveRoute } from '$app/paths';
</script>

<a data-id="target" href={resolveRoute('/resolve-route/[foo]', { foo: 'resolved' })}>click me</a>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<script>
import { page } from '$app/stores';
</script>

<h2>{$page.params.foo}</h2>
7 changes: 7 additions & 0 deletions packages/kit/test/apps/options/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@ test.describe('base path', () => {
await clicknav('[href="/path-base/base/two"]');
expect(await page.textContent('h2')).toBe('two');
});

test('resolveRoute accounts for base path', async ({ baseURL, page, clicknav }) => {
await page.goto('/path-base/resolve-route');
await clicknav('[data-id=target]');
expect(page.url()).toBe(`${baseURL}/path-base/resolve-route/resolved/`);
expect(await page.textContent('h2')).toBe('resolved');
});
});

test.describe('assets path', () => {
Expand Down
16 changes: 16 additions & 0 deletions packages/kit/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1737,6 +1737,8 @@ declare module '@sveltejs/kit' {
* */
export function fail<T extends Record<string, unknown> | undefined = undefined>(status: number, data: T): ActionFailure<T>;
/**
* @deprecated Use `resolveRoute` from `$app/paths` instead.
*
* Populate a route ID with params to resolve a pathname.
* @example
* ```js
Expand Down Expand Up @@ -2026,6 +2028,20 @@ declare module '$app/navigation' {

declare module '$app/paths' {
export { base, assets } from '__sveltekit/paths';
/**
* Populate a route ID with params to resolve a pathname.
* @example
* ```js
* resolveRoute(
* `/blog/[slug]/[...somethingElse]`,
* {
* slug: 'hello-world',
* somethingElse: 'something/else'
* }
* ); // `/blog/hello-world/something/else`
* ```
* */
export function resolveRoute(id: string, params: Record<string, string | undefined>): string;
}

declare module '$app/stores' {
Expand Down

0 comments on commit ac6c3cb

Please sign in to comment.