Skip to content

Commit

Permalink
feat: support custom pathToRegexpModule (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
fengmk2 authored Jan 22, 2025
1 parent 4c7b10f commit 694acc8
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 27 deletions.
15 changes: 7 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
[![Test coverage](https://img.shields.io/codecov/c/github/eggjs/egg-path-matching.svg?style=flat-square)](https://codecov.io/gh/eggjs/egg-path-matching)
[![Known Vulnerabilities][snyk-image]][snyk-url]
[![npm download][download-image]][download-url]
[![Node.js Version](https://img.shields.io/node/v/egg-path-matching.svg?style=flat)](https://nodejs.org/en/download/)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://makeapullrequest.com)
![CodeRabbit Pull Request Reviews](https://img.shields.io/coderabbit/prs/github/eggjs/egg-path-matching)

[npm-image]: https://img.shields.io/npm/v/egg-path-matching.svg?style=flat-square
[npm-url]: https://npmjs.org/package/egg-path-matching
Expand Down Expand Up @@ -33,6 +36,8 @@ const options = {
ignore: [ ctx => ctx.path.startsWith('/api'), /^\/foo$/, '/bar'],
// support match or ignore
match: '/api',
// custom path-to-regexp module, default is `path-to-regexp@1`
// pathToRegexpModule: require('path-to-regexp'),
};

const match = pathMatching(options);
Expand All @@ -52,14 +57,8 @@ assert(match({ path: '/api' }) === true);

[MIT](LICENSE)

<!-- GITCONTRIBUTOR_START -->

## Contributors

|[<img src="https://avatars.githubusercontent.com/u/985607?v=4" width="100px;"/><br/><sub><b>dead-horse</b></sub>](https://github.com/dead-horse)<br/>|[<img src="https://avatars.githubusercontent.com/u/156269?v=4" width="100px;"/><br/><sub><b>fengmk2</b></sub>](https://github.com/fengmk2)<br/>|[<img src="https://avatars.githubusercontent.com/u/7903541?v=4" width="100px;"/><br/><sub><b>releasethecow</b></sub>](https://github.com/releasethecow)<br/>|[<img src="https://avatars.githubusercontent.com/u/227713?v=4" width="100px;"/><br/><sub><b>atian25</b></sub>](https://github.com/atian25)<br/>|[<img src="https://avatars.githubusercontent.com/u/5102113?v=4" width="100px;"/><br/><sub><b>xyeric</b></sub>](https://github.com/xyeric)<br/>|
| :---: | :---: | :---: | :---: | :---: |


This project follows the git-contributor [spec](https://github.com/xudafeng/git-contributor), auto updated at `Thu Dec 14 2023 17:20:14 GMT+0800`.
[![Contributors](https://contrib.rocks/image?repo=eggjs/egg-path-matching)](https://github.com/eggjs/egg-path-matching/graphs/contributors)

<!-- GITCONTRIBUTOR_END -->
Made with [contributors-img](https://contrib.rocks).
44 changes: 31 additions & 13 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,54 @@
'use strict';

const pathToRegexp = require('path-to-regexp');

module.exports = function(options) {
options = options || {};
if (options.match && options.ignore) throw new Error('options.match and options.ignore can not both present');
if (!options.match && !options.ignore) return () => true;
if (options.match && options.ignore) {
throw new Error('options.match and options.ignore can not both present');
}
if (!options.match && !options.ignore) {
return () => true;
}

const matchFn = options.match ? toPathMatch(options.match) : toPathMatch(options.ignore);
const pathToRegexpModule = options.pathToRegexpModule || require('path-to-regexp');
const pathToRegexp = pathToRegexpModule.pathToRegexp || pathToRegexpModule;
const matchFn = options.match ?
toPathMatch(options.match, pathToRegexp) : toPathMatch(options.ignore, pathToRegexp);

return function pathMatch(ctx) {
const matched = matchFn(ctx);
return options.match ? matched : !matched;
};
};

function toPathMatch(pattern) {
function toPathMatch(pattern, pathToRegexp) {
if (typeof pattern === 'string') {
const reg = pathToRegexp(pattern, [], { end: false });
if (reg.global) reg.lastIndex = 0;
let reg = pathToRegexp(pattern, [], { end: false });
if (reg.regexp) {
// support path-to-regexp@8
// => const { regexp, keys } = pathToRegexp("/foo/:bar");
reg = reg.regexp;
}
if (reg.global) {
reg.lastIndex = 0;
}
return ctx => reg.test(ctx.path);
}

if (pattern instanceof RegExp) {
return ctx => {
if (pattern.global) pattern.lastIndex = 0;
if (pattern.global) {
pattern.lastIndex = 0;
}
return pattern.test(ctx.path);
};
}
if (typeof pattern === 'function') return pattern;

if (typeof pattern === 'function') {
return pattern;
}

if (Array.isArray(pattern)) {
const matchs = pattern.map(item => toPathMatch(item));
const matchs = pattern.map(item => toPathMatch(item, pathToRegexp));
return ctx => matchs.some(match => match(ctx));
}

throw new Error('match/ignore pattern must be RegExp, Array or String, but got ' + pattern);
}
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
"index.js"
],
"scripts": {
"pretest": "npm run lint -- --fix",
"test": "egg-bin test",
"cov": "egg-bin cov",
"lint": "eslint *.js test",
"ci": "npm run lint && npm run cov",
"contributor": "git-contributor"
"preci": "npm run lint",
"ci": "npm run cov"
},
"keywords": [
"url",
Expand All @@ -32,12 +33,12 @@
},
"license": "MIT",
"dependencies": {
"path-to-regexp": "^1.7.0"
"path-to-regexp": "^1.9.0"
},
"devDependencies": {
"egg-bin": "^6.5.2",
"eslint": "^8.55.0",
"eslint-config-egg": "12",
"git-contributor": "^2.1.5"
"path-to-regexp-v8": "npm:path-to-regexp@8"
}
}
11 changes: 9 additions & 2 deletions test/index.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
'use strict';

const assert = require('assert');
const match = require('..');

Expand Down Expand Up @@ -28,6 +26,15 @@ describe('egg-path-matching', () => {
assert(fn({ path: '/api1' }) === false);
});

it('support custom pathToRegexpModule', () => {
const fn = match({ match: '/api{/*path}', pathToRegexpModule: require('path-to-regexp-v8') });
assert(fn({ path: '/api/hello' }) === true);
assert(fn({ path: '/api/' }) === true);
assert(fn({ path: '/api' }) === true);
assert(fn({ path: '/api1/hello' }) === false);
assert(fn({ path: '/api1' }) === false);
});

it('support regexp', () => {
const fn = match({ match: /^\/api/ });
assert(fn({ path: '/api/hello' }) === true);
Expand Down

0 comments on commit 694acc8

Please sign in to comment.