mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-10 04:22:12 +00:00
[now dev] Use pcre-to-regexp to match routes (#2027)
* [now dev] Use `pcre-to-regexp` to match `routes` The now.json `routes` support PCRE syntax like named captures, so use the `pcre-to-regexp` module to match the routes. Fixes #2023. * Pass the resolved router `dest` and query params to the Lambda
This commit is contained in:
committed by
Leo Lamprecht
parent
6c8dc90267
commit
fd3c110c02
3
@types/pcre-to-regexp/index.d.ts
vendored
Normal file
3
@types/pcre-to-regexp/index.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
declare module 'pcre-to-regexp' {
|
||||
export default function (pattern: string, keys?: string[]): RegExp
|
||||
}
|
||||
@@ -208,6 +208,7 @@
|
||||
"npm-package-arg": "6.1.0",
|
||||
"nyc": "13.2.0",
|
||||
"ora": "1.3.0",
|
||||
"pcre-to-regexp": "0.0.4",
|
||||
"pkg": "4.3.7",
|
||||
"pluralize": "7.0.0",
|
||||
"pre-commit": "1.2.2",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import url from 'url';
|
||||
import qs from 'querystring';
|
||||
import PCRE from 'pcre-to-regexp';
|
||||
|
||||
import isURL from './is-url';
|
||||
|
||||
@@ -12,12 +13,39 @@ export default function(reqPath = '', routes?: RouteConfig[]): RouteResult {
|
||||
// try route match
|
||||
if (routes) {
|
||||
routes.find((routeConfig: RouteConfig, idx: number) => {
|
||||
const matcher = new RegExp('^' + routeConfig.src + '$');
|
||||
let { src } = routeConfig;
|
||||
|
||||
if (matcher.test(reqPathname)) {
|
||||
const destPath = routeConfig.dest
|
||||
? reqPathname.replace(matcher, routeConfig.dest)
|
||||
: reqPathname;
|
||||
if (!src.startsWith('^')) {
|
||||
src = `^${src}`;
|
||||
}
|
||||
|
||||
if (!src.endsWith('$')) {
|
||||
src = `${src}$`;
|
||||
}
|
||||
|
||||
const keys: string[] = [];
|
||||
const matcher = PCRE(`%${src}%i`, keys);
|
||||
const match = matcher.exec(reqPathname);
|
||||
|
||||
if (match) {
|
||||
let destPath: string = reqPathname;
|
||||
if (routeConfig.dest) {
|
||||
destPath = routeConfig.dest.replace(
|
||||
/\$([1-9a-zA-Z]+)/g,
|
||||
(_, param) => {
|
||||
let matchIndex: number = keys.indexOf(param);
|
||||
if (matchIndex === -1) {
|
||||
// It's a number match, not a named capture
|
||||
matchIndex = parseInt(param, 10);
|
||||
} else {
|
||||
// For named captures, add one to the `keys` index to
|
||||
// match up with the RegExp group matches
|
||||
matchIndex++;
|
||||
}
|
||||
return match[matchIndex];
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (isURL(destPath)) {
|
||||
found = {
|
||||
|
||||
@@ -316,10 +316,14 @@ export default class DevServer {
|
||||
}
|
||||
|
||||
const body = await rawBody(req);
|
||||
let path: string = dest;
|
||||
if (Object.keys(uri_args || {}).length > 0) {
|
||||
path += `?${qs.stringify(uri_args)}`;
|
||||
}
|
||||
|
||||
const payload: InvokePayload = {
|
||||
method: req.method || 'GET',
|
||||
path: req.url || '/',
|
||||
path,
|
||||
headers: req.headers,
|
||||
encoding: 'base64',
|
||||
body: body.toString('base64')
|
||||
|
||||
@@ -36,7 +36,7 @@ test('[dev-router] captured groups', t => {
|
||||
|
||||
test('[dev-router] named groups', t => {
|
||||
const routesConfig = [
|
||||
{ src: '/user/(?<id>.+)', dest: '/user.js?id=$<id>' }
|
||||
{ src: '/user/(?<id>.+)', dest: '/user.js?id=$id' }
|
||||
];
|
||||
const result = devRouter('/user/123', routesConfig);
|
||||
|
||||
|
||||
@@ -5448,6 +5448,11 @@ path-type@^3.0.0:
|
||||
dependencies:
|
||||
pify "^3.0.0"
|
||||
|
||||
pcre-to-regexp@0.0.4:
|
||||
version "0.0.4"
|
||||
resolved "https://registry.yarnpkg.com/pcre-to-regexp/-/pcre-to-regexp-0.0.4.tgz#a19c3fc6af540349f915367a4776c75c651dae05"
|
||||
integrity sha1-oZw/xq9UA0n5FTZ6R3bHXGUdrgU=
|
||||
|
||||
pend@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
|
||||
|
||||
Reference in New Issue
Block a user