Skip to content

Commit f427d47

Browse files
dummdidummRich Harris
and
Rich Harris
authored
fix: construct correct pathname for isr from route with nested params (#9470)
* fix: constructor correct pathname for isr from route with nested params fixes #9459 * remove extraneous slashes * typo * remove logging --------- Co-authored-by: Rich Harris <[email protected]>
1 parent a243aa6 commit f427d47

File tree

7 files changed

+79
-10
lines changed

7 files changed

+79
-10
lines changed

.changeset/heavy-news-argue.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/adapter-vercel': patch
3+
---
4+
5+
fix: construct correct pathname for isr from route with nested params

packages/adapter-vercel/files/serverless.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ export default async (req, res) => {
2222
const [path, search] = req.url.split('?');
2323

2424
const params = new URLSearchParams(search);
25-
const pathname = params.get('__pathname');
25+
let pathname = params.get('__pathname');
2626

2727
if (pathname) {
2828
params.delete('__pathname');
29+
// Optional routes' pathname replacements look like `/foo/$1/bar` which means we could end up with an url like /foo//bar
30+
pathname = pathname.replace(/\/+/g, '/');
2931
req.url = `${pathname}${path.endsWith(DATA_SUFFIX) ? DATA_SUFFIX : ''}?${params}`;
3032
}
3133
}

packages/adapter-vercel/index.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import path from 'node:path';
33
import { fileURLToPath } from 'node:url';
44
import { nodeFileTrace } from '@vercel/nft';
55
import esbuild from 'esbuild';
6+
import { get_pathname } from './utils.js';
67

78
const VALID_RUNTIMES = ['edge', 'nodejs16.x', 'nodejs18.x'];
89

@@ -292,13 +293,7 @@ const plugin = function (defaults = {}) {
292293
fs.symlinkSync(relative, `${base}.func`);
293294
fs.symlinkSync(`../${relative}`, `${base}/__data.json.func`);
294295

295-
let i = 1;
296-
const pathname = route.segments
297-
.map((segment) => {
298-
return segment.dynamic ? `$${i++}` : segment.content;
299-
})
300-
.join('/');
301-
296+
const pathname = get_pathname(route);
302297
const json = JSON.stringify(isr, null, '\t');
303298

304299
write(`${base}.prerender-config.json`, json);

packages/adapter-vercel/package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@
2121
"files": [
2222
"files",
2323
"index.js",
24+
"utils.js",
2425
"index.d.ts"
2526
],
2627
"scripts": {
2728
"lint": "prettier --check . --config ../../.prettierrc --ignore-path .gitignore",
2829
"format": "pnpm lint --write",
29-
"check": "tsc"
30+
"check": "tsc",
31+
"test": "uvu test .spec.js"
3032
},
3133
"dependencies": {
3234
"@vercel/nft": "^0.22.1",
@@ -35,7 +37,8 @@
3537
"devDependencies": {
3638
"@sveltejs/kit": "workspace:^",
3739
"@types/node": "^16.18.6",
38-
"typescript": "^4.9.4"
40+
"typescript": "^4.9.4",
41+
"uvu": "^0.5.6"
3942
},
4043
"peerDependencies": {
4144
"@sveltejs/kit": "^1.5.0"
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { test } from 'uvu';
2+
import * as assert from 'uvu/assert';
3+
import { get_pathname } from '../utils.js';
4+
5+
/**
6+
* @param {import('@sveltejs/kit').RouteDefinition<any>['segments']} segments
7+
* @param {string} expected
8+
*/
9+
function run_get_pathname_test(segments, expected) {
10+
const route = /** @type {import('@sveltejs/kit').RouteDefinition<any>} */ ({ segments });
11+
assert.equal(get_pathname(route), expected);
12+
}
13+
14+
test('get_pathname for simple route', () => {
15+
run_get_pathname_test([{ content: 'foo', dynamic: false, rest: false }], 'foo');
16+
});
17+
18+
test('get_pathname for route with parameters', () => {
19+
run_get_pathname_test(
20+
[
21+
{ content: 'foo', dynamic: false, rest: false },
22+
{ content: '[bar]', dynamic: true, rest: false }
23+
],
24+
'foo/$1'
25+
);
26+
});
27+
28+
test('get_pathname for route with parameters within segment', () => {
29+
run_get_pathname_test(
30+
[
31+
{ content: 'foo-[bar]', dynamic: true, rest: false },
32+
{ content: '[baz]-buz', dynamic: true, rest: false }
33+
],
34+
'foo-$1/$2-buz'
35+
);
36+
});
37+
38+
test.run();

packages/adapter-vercel/utils.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/** @param {import("@sveltejs/kit").RouteDefinition<any>} route */
2+
export function get_pathname(route) {
3+
let i = 1;
4+
5+
return route.segments
6+
.map((segment) => {
7+
if (!segment.dynamic) {
8+
return segment.content;
9+
}
10+
11+
const parts = segment.content.split(/\[(.+?)\](?!\])/);
12+
return parts
13+
.map((content, j) => {
14+
if (j % 2) {
15+
return `$${i++}`;
16+
} else {
17+
return content;
18+
}
19+
})
20+
.join('');
21+
})
22+
.join('/');
23+
}

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)