-
Notifications
You must be signed in to change notification settings - Fork 122
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: named captures in
has
fields not applying to route dest (#449)
- Loading branch information
1 parent
1e25a97
commit 0168496
Showing
6 changed files
with
163 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@cloudflare/next-on-pages': patch | ||
--- | ||
|
||
Fix named capture groups in `has` entries in the build output config not applying to route destination paths. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 53 additions & 13 deletions
66
packages/next-on-pages/templates/_worker.js/utils/matcher.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,46 +1,86 @@ | ||
import { applyPCREMatches, matchPCRE } from './pcre'; | ||
|
||
type HasFieldRequestProperties = { | ||
url: URL; | ||
cookies: Record<string, string>; | ||
headers: Headers; | ||
routeDest?: string; | ||
}; | ||
|
||
/** | ||
* Checks if a Vercel source route's `has` record conditions match a request. | ||
* Checks if a Vercel source route's `has` record conditions match a request, and whether the request | ||
* destination should be updated based on the `has` record. | ||
* | ||
* @param has The `has` record conditions to check against the request. | ||
* @param requestProperties The request properties to check against. | ||
* @returns Whether the request matches the `has` record conditions. | ||
* @returns Whether the request matches the `has` record conditions, and the new destination if it changed. | ||
*/ | ||
export function hasField( | ||
export function checkhasField( | ||
has: VercelHasField, | ||
{ url, cookies, headers }: HasFieldRequestProperties, | ||
): boolean { | ||
{ url, cookies, headers, routeDest }: HasFieldRequestProperties, | ||
): { valid: boolean; newRouteDest?: string } { | ||
switch (has.type) { | ||
case 'host': { | ||
return url.hostname === has.value; | ||
return { valid: url.hostname === has.value }; | ||
} | ||
case 'header': { | ||
if (has.value !== undefined) { | ||
return !!headers.get(has.key)?.match(has.value); | ||
return getHasFieldPCREMatchResult( | ||
has.value, | ||
headers.get(has.key), | ||
routeDest, | ||
); | ||
} | ||
|
||
return headers.has(has.key); | ||
return { valid: headers.has(has.key) }; | ||
} | ||
case 'cookie': { | ||
const cookie = cookies[has.key]; | ||
|
||
if (has.value !== undefined) { | ||
return !!cookie?.match(has.value); | ||
if (cookie && has.value !== undefined) { | ||
return getHasFieldPCREMatchResult(has.value, cookie, routeDest); | ||
} | ||
|
||
return cookie !== undefined; | ||
return { valid: cookie !== undefined }; | ||
} | ||
case 'query': { | ||
if (has.value !== undefined) { | ||
return !!url.searchParams.get(has.key)?.match(has.value); | ||
return getHasFieldPCREMatchResult( | ||
has.value, | ||
url.searchParams.get(has.key), | ||
routeDest, | ||
); | ||
} | ||
|
||
return url.searchParams.has(has.key); | ||
return { valid: url.searchParams.has(has.key) }; | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Gets the has field PCRE match results, and tries to apply any named capture groups to a | ||
* route destination. | ||
* | ||
* @param hasValue The has field value to match against. | ||
* @param foundValue The value found in the request. | ||
* @param routeDest Destination to apply match to. | ||
* @returns Whether the match is valid, and the destination with the match applied. | ||
*/ | ||
function getHasFieldPCREMatchResult( | ||
hasValue: string, | ||
foundValue: string | null, | ||
routeDest?: string, | ||
): { valid: boolean; newRouteDest?: string } { | ||
const { match, captureGroupKeys } = matchPCRE(hasValue, foundValue); | ||
|
||
if (routeDest && match && captureGroupKeys.length) { | ||
return { | ||
valid: !!match, | ||
newRouteDest: applyPCREMatches(routeDest, match, captureGroupKeys, { | ||
namedOnly: true, | ||
}), | ||
}; | ||
} | ||
|
||
return { valid: !!match }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
77 changes: 58 additions & 19 deletions
77
packages/next-on-pages/tests/templates/utils/matcher.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.