mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-11 04:22:13 +00:00
[routing-utils] Allow passing internal params to convertRewrites (#6742)
This adds an argument to allow passing internal param names that should be ignored when considering whether params should be auto-added to a rewrite's destination query. After adding this we should be able to resolve https://github.com/vercel/next.js/issues/27563 in the runtime where `convertRewrites` is called.
This matches Next.js' handling for internal params which can be seen [here](e90825ad88/packages/next/shared/lib/router/utils/prepare-destination.ts (L203))
### Related Issues
x-ref: https://github.com/vercel/next.js/issues/27563
### 📋 Checklist
<!--
Please keep your PR as a Draft until the checklist is complete
-->
#### Tests
- [x] The code changed/added as part of this PR has been covered with tests
- [x] All tests pass locally with `yarn test-unit`
#### Code Review
- [ ] This PR has a concise title and thorough description useful to a reviewer
- [ ] Issue from task tracker has a link to this PR
This commit is contained in:
@@ -77,12 +77,21 @@ export function convertRedirects(
|
||||
});
|
||||
}
|
||||
|
||||
export function convertRewrites(rewrites: Rewrite[]): Route[] {
|
||||
export function convertRewrites(
|
||||
rewrites: Rewrite[],
|
||||
internalParamNames?: string[]
|
||||
): Route[] {
|
||||
return rewrites.map(r => {
|
||||
const { src, segments } = sourceToRegex(r.source);
|
||||
const hasSegments = collectHasSegments(r.has);
|
||||
try {
|
||||
const dest = replaceSegments(segments, hasSegments, r.destination);
|
||||
const dest = replaceSegments(
|
||||
segments,
|
||||
hasSegments,
|
||||
r.destination,
|
||||
false,
|
||||
internalParamNames
|
||||
);
|
||||
const route: Route = { src, dest, check: true };
|
||||
|
||||
if (r.has) {
|
||||
@@ -220,7 +229,8 @@ function replaceSegments(
|
||||
segments: string[],
|
||||
hasItemSegments: string[],
|
||||
destination: string,
|
||||
isRedirect?: boolean
|
||||
isRedirect?: boolean,
|
||||
internalParamNames?: string[]
|
||||
): string {
|
||||
const namedSegments = segments.filter(name => name !== UN_NAMED_SEGMENT);
|
||||
const canNeedReplacing =
|
||||
@@ -296,7 +306,13 @@ function replaceSegments(
|
||||
// or more params aren't already used in the destination's path
|
||||
const paramKeys = Object.keys(indexes);
|
||||
const needsQueryUpdating =
|
||||
!isRedirect && !paramKeys.some(param => destParams.has(param));
|
||||
// we do not consider an internal param since it is added automatically
|
||||
!isRedirect &&
|
||||
!paramKeys.some(
|
||||
param =>
|
||||
!(internalParamNames && internalParamNames.includes(param)) &&
|
||||
destParams.has(param)
|
||||
);
|
||||
|
||||
if (needsQueryUpdating) {
|
||||
for (const param of paramKeys) {
|
||||
|
||||
18
packages/routing-utils/test/superstatic.spec.js
vendored
18
packages/routing-utils/test/superstatic.spec.js
vendored
@@ -471,7 +471,8 @@ test('convertRedirects', () => {
|
||||
});
|
||||
|
||||
test('convertRewrites', () => {
|
||||
const actual = convertRewrites([
|
||||
const actual = convertRewrites(
|
||||
[
|
||||
{ source: '/some/old/path', destination: '/some/new/path' },
|
||||
{ source: '/proxy/(.*)', destination: 'https://www.firebase.com' },
|
||||
{ source: '/proxy/(.*)', destination: 'https://www.firebase.com/' },
|
||||
@@ -579,7 +580,13 @@ test('convertRewrites', () => {
|
||||
source: '/array-query-string/:id/:name',
|
||||
destination: 'https://example.com/?tag=1&tag=2',
|
||||
},
|
||||
]);
|
||||
{
|
||||
source: '/:nextInternalLocale/:path',
|
||||
destination: '/api/hello',
|
||||
},
|
||||
],
|
||||
['nextInternalLocale']
|
||||
);
|
||||
|
||||
const expected = [
|
||||
{ src: '^\\/some\\/old\\/path$', dest: '/some/new/path', check: true },
|
||||
@@ -728,6 +735,11 @@ test('convertRewrites', () => {
|
||||
dest: 'https://example.com/?tag=1&tag=2&id=$1&name=$2',
|
||||
check: true,
|
||||
},
|
||||
{
|
||||
check: true,
|
||||
dest: '/api/hello?nextInternalLocale=$1&path=$2',
|
||||
src: '^(?:\\/([^\\/]+?))(?:\\/([^\\/]+?))$',
|
||||
},
|
||||
];
|
||||
|
||||
deepEqual(actual, expected);
|
||||
@@ -755,6 +767,7 @@ test('convertRewrites', () => {
|
||||
['/hello/world'],
|
||||
['/hello/world'],
|
||||
['/array-query-string/10/email'],
|
||||
['/en/hello'],
|
||||
];
|
||||
|
||||
const mustNotMatch = [
|
||||
@@ -780,6 +793,7 @@ test('convertRewrites', () => {
|
||||
['/hllooo'],
|
||||
['/hllooo'],
|
||||
['/array-query-string/10'],
|
||||
['/en/hello/world', '/en/hello/'],
|
||||
];
|
||||
|
||||
assertRegexMatches(actual, mustMatch, mustNotMatch);
|
||||
|
||||
Reference in New Issue
Block a user