Skip to content

Commit

Permalink
fix: resolve issues caused by path-to-regexp. (#335)
Browse files Browse the repository at this point in the history
  • Loading branch information
jaywcjlove committed Dec 7, 2024
1 parent fc7b2de commit 400d176
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 25 deletions.
7 changes: 4 additions & 3 deletions example/base/mocker/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ const proxy = {
console.log(req.params); // false
return res.json({ test: true });
},
'GET /api/:owner/:repo/raw/:ref/(.*)': (req, res) => {
'GET /api/:owner/:repo/raw/:ref/*path': (req, res) => {
console.log(req.params); // false
return res.json({ test: true });
return res.json({ test: true, path: req.params.path });
},
'GET /repos/hello': (req, res) => {
return res.json({
Expand All @@ -54,8 +54,9 @@ const proxy = {
},

'GET /api/jobs/:id': (req, res) => {
console.log('---->', req.params)
return res.json({
text: 'url: /api/jobs/:id'
text: `url: /api/jobs/${req.params.id}`
});
},

Expand Down
2 changes: 1 addition & 1 deletion example/create-react-app/src/setupProxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const path = require('path');
module.exports = function(app) {
apiMocker(app, path.resolve('./mocker/index.js'), {
proxy: {
'/repos/(.*)': 'https://api.github.com/',
'/repos/*path': 'https://api.github.com/',
},
changeHost: true,
});
Expand Down
8 changes: 4 additions & 4 deletions example/express/mocker/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,17 +76,17 @@ const proxy = {
console.log('---->', req.params.id)
res.send({ status: 'ok', message: '删除成功!' });
},
'GET /api/:owner/:repo/raw/:ref/(.*)': (req, res) => {
const { owner, repo, ref } = req.params;
'GET /api/:owner/:repo/raw/:ref/*path': (req, res) => {
const { owner, repo, ref, path } = req.params;
// http://localhost:8081/api/admin/webpack-mock-api/raw/master/add/ddd.md
// owner => admin
// repo => webpack-mock-api
// ref => master
// req.params[0] => add/ddd.md
// req.params.path => add/ddd.md
return res.json({
id: 1,
owner, repo, ref,
path: req.params[0]
path: path
});
},
}
Expand Down
4 changes: 2 additions & 2 deletions example/typescript/mocker/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ const proxy = {
console.log(req.params); // false
return res.json({ test: true });
},
'GET /api/:owner/:repo/raw/:ref/(.*)': (req, res) => {
'GET /api/:owner/:repo/raw/:ref/*path': (req, res) => {
console.log(req.params); // false
return res.json({ test: true });
return res.json({ test: true, path: req.params.path });
},
'GET /repos/hello': (req, res) => {
return res.json({
Expand Down
27 changes: 21 additions & 6 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,17 +275,27 @@ export default function mockerApi(app: Application, watchFile: string | string[]
* Get Proxy key
*/
const proxyKey = Object.keys(options.proxy).find((kname) => {
const { regexp } = pathToRegexp(kname.replace((new RegExp('^' + req.method + ' ')), ''))
return !!regexp.exec(getExecUrlPath(req));
try {
const { regexp } = pathToRegexp(kname.replace((new RegExp('^' + req.method + ' ')), ''))
return !!regexp.exec(getExecUrlPath(req));
} catch (error) {
console.error(`${color.red_b.black(' Failed: ')} The proxy configuration ${color.red(kname)} contains a syntax error!!\n doc: ${color.blue("https://www.npmjs.com/package/path-to-regexp/v/8.2.0")}`);
return false;
}
});
/**
* Get Mocker key
* => `GET /api/:owner/:repo/raw/:ref`
* => `GET /api/:owner/:repo/raw/:ref/(.*)`
*/
const mockerKey: string = Object.keys(mocker).find((kname) => {
const { regexp } = pathToRegexp(kname.replace((new RegExp('^' + req.method + ' ')), ''))
return !!regexp.exec(getExecUrlPath(req));
try {
const { regexp } = pathToRegexp(kname.replace((new RegExp('^' + req.method + ' ')), ''))
return !!regexp.exec(getExecUrlPath(req));
} catch (error) {
console.error(`${color.red_b.black(' Failed: ')} The mocker configuration ${color.red(kname)} contains a syntax error!!\n doc: ${color.blue("https://www.npmjs.com/package/path-to-regexp/v/8.2.0")}`);
return false;
}
});
/**
* Access Control Allow options.
Expand All @@ -302,8 +312,13 @@ export default function mockerApi(app: Application, watchFile: string | string[]
res.setHeader(keyName, accessOptions[keyName]);
});
const proxyKeyString: string = Object.keys(mocker).find((kname) => {
const { regexp } = pathToRegexp(kname.replace((new RegExp('^(PUT|POST|GET|DELETE) ')), ''))
return !!regexp.exec(getExecUrlPath(req))
try {
const { regexp } = pathToRegexp(kname.replace((new RegExp('^(PUT|POST|GET|DELETE) ')), ''))
return !!regexp.exec(getExecUrlPath(req))
} catch (error) {
console.error(`${color.red_b.black(' Failed: ')} The mocker configuration ${color.red(kname)} contains a syntax error!!\n doc: ${color.blue("https://www.npmjs.com/package/path-to-regexp/v/8.2.0")}`);
return false;
}
})
// fix issue 34 https://github.com/jaywcjlove/mocker-api/issues/34
// In some cross-origin http request, the browser will send the preflighted options request before sending the request methods written in the code.
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/mockerHandle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export function mockerHandle(param: MockerHandleOptions) {
const result = mocker[mockerKey];
if (typeof result === 'function') {
const rgxStr = ~mockerKey.indexOf(' ') ? ' ' : '';
req.params = pathMatch({ sensitive: false, strict: false, end: false })(mockerKey.split(new RegExp(rgxStr))[1])(URL.parse(req.url).pathname);
req.params = pathMatch({ sensitive: false, trailing: false, end: false })(mockerKey.split(new RegExp(rgxStr))[1])(URL.parse(req.url).pathname);
result(req, res, next);
} else {
res.json(result);
Expand Down
22 changes: 14 additions & 8 deletions packages/core/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@

import * as toRegexp from 'path-to-regexp';
import { TokensToRegexpOptions, ParseOptions, Key } from 'path-to-regexp';
import type { PathToRegexpOptions, ParseOptions, Keys } from 'path-to-regexp';

const pathToRegexp = toRegexp.pathToRegexp;

export function pathMatch(options: TokensToRegexpOptions & ParseOptions) {
export function pathMatch(options: PathToRegexpOptions & ParseOptions) {
options = options || {};
return function (path: string) {
var keys: (Key & TokensToRegexpOptions & ParseOptions & { repeat: boolean })[] = [];
var re = pathToRegexp(path, keys, options);
var keys: Keys = [];
let regexpObject: RegExp | undefined = undefined
try {
var re = pathToRegexp(path, options);
regexpObject = re.regexp;
keys = re.keys;
} catch (error) {
console.error(error);
}
return function (pathname: string, params?: any) {
var m = re.exec(pathname);
if (!m) return false;
var mData = regexpObject?.exec(pathname);
if (!mData) return false;
params = params || {};
var key, param;
for (var i = 0; i < keys.length; i++) {
key = keys[i];
param = m[i + 1];
param = mData[i + 1];
if (!param) continue;
params[key.name] = decodeURIComponent(param);
if (key.repeat) params[key.name] = params[key.name].split(key.delimiter)
}
return params;
}
Expand Down

0 comments on commit 400d176

Please sign in to comment.