├── .eslintrc ├── .github └── workflows │ └── node.js.yml ├── .gitignore ├── LICENSE ├── README.md ├── __tests__ ├── .eslintrc └── index.js ├── index.js ├── package-lock.json └── package.json /.eslintrc: -------------------------------------------------------------------------------- 1 | --- 2 | extends: standard -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | 3 | on: push 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | strategy: 11 | matrix: 12 | node-version: [10.x, 12.x] 13 | 14 | env: 15 | CI: true 16 | CODECOV_TOKEN: 50b38e30-ed18-4290-96c7-0e1592f6d8a2 17 | 18 | steps: 19 | - uses: actions/checkout@v2 20 | - name: Use Node.js ${{ matrix.node-version }} 21 | uses: actions/setup-node@v1 22 | with: 23 | node-version: ${{ matrix.node-version }} 24 | - run: npm ci 25 | - run: npm run eslint 26 | - run: npm run test -- --coverage 27 | - run: npx codecov -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .DS_Store* 3 | *.log 4 | *.gz 5 | 6 | node_modules 7 | coverage 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | (The MIT License) 3 | 4 | Copyright (c) 2014 segmentio <team@segment.io> 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | 'Software'), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be 15 | included in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > [!CAUTION] 2 | > **This repository is archived and no longer actively maintained.** 3 | > 4 | > We are no longer accepting issues, feature requests, or pull requests. 5 | > For additional support or questions, please visit the [Express.js Discussions page](https://github.com/expressjs/express/discussions). 6 | 7 | 8 | 9 | # path match 10 | 11 | [![NPM version][npm-image]][npm-url] 12 | [![Node.js CI](https://github.com/pillarjs/path-match/workflows/Node.js%20CI/badge.svg?branch=master)](https://github.com/pillarjs/path-match/actions?query=workflow%3A%22Node.js+CI%22) 13 | [![codecov](https://codecov.io/gh/pillarjs/path-match/branch/master/graph/badge.svg)](https://codecov.io/gh/pillarjs/path-match) 14 | [![Dependency Status][david-image]][david-url] 15 | [![License][license-image]][license-url] 16 | [![Downloads][downloads-image]][downloads-url] 17 | 18 | Thin wrapper around [path-to-regexp](https://github.com/component/path-to-regexp) to make extracting the param names easier. 19 | 20 | ```js 21 | var route = require('path-match')({ 22 | // path-to-regexp options 23 | sensitive: false, 24 | strict: false, 25 | end: false, 26 | }); 27 | 28 | // create a match function from a route 29 | var match = route('/post/:id'); 30 | 31 | // match a route 32 | var parse = require('url').parse; 33 | require('http').createServer(function (req, res) { 34 | var params = match(parse(req.url).pathname); 35 | 36 | // no match 37 | if (params === false) { 38 | res.statusCode = 404; 39 | res.end(); 40 | return; 41 | } 42 | 43 | // the matched id 44 | var id = params.id; 45 | 46 | // do stuff with the ID 47 | }) 48 | ``` 49 | 50 | [npm-image]: https://img.shields.io/npm/v/path-match.svg?style=flat-square 51 | [npm-url]: https://npmjs.org/package/path-match 52 | [david-image]: http://img.shields.io/david/pillarjs/path-match.svg?style=flat-square 53 | [david-url]: https://david-dm.org/pillarjs/path-match 54 | [license-image]: http://img.shields.io/npm/l/path-match.svg?style=flat-square 55 | [license-url]: LICENSE.md 56 | [downloads-image]: http://img.shields.io/npm/dm/path-match.svg?style=flat-square 57 | [downloads-url]: https://npmjs.org/package/path-match 58 | -------------------------------------------------------------------------------- /__tests__/.eslintrc: -------------------------------------------------------------------------------- 1 | --- 2 | env: 3 | jest: true -------------------------------------------------------------------------------- /__tests__/index.js: -------------------------------------------------------------------------------- 1 | 2 | var assert = require('assert') 3 | 4 | var route = require('..')() 5 | 6 | it('/%%%', function () { 7 | var match = route('/:a') 8 | try { 9 | match('/%%%') 10 | throw new Error('jklajsldkfjasdf') 11 | } catch (err) { 12 | assert(~err.message.indexOf('"%%%"')) 13 | assert.equal(err.status, 400) 14 | } 15 | }) 16 | 17 | it('/:a/:b', function () { 18 | var match = route('/:a/:b') 19 | var params = match('/a/b') 20 | assert.deepEqual(params, { 21 | a: 'a', 22 | b: 'b' 23 | }) 24 | }) 25 | 26 | it('/:a/b', function () { 27 | var match = route('/:a/b') 28 | var params = match('/a/b') 29 | assert.deepEqual(params, { 30 | a: 'a' 31 | }) 32 | }) 33 | 34 | it('/:a/b/:c', function () { 35 | var match = route('/:a/b/:c') 36 | var params = match('/a/b/c') 37 | assert.deepEqual(params, { 38 | a: 'a', 39 | c: 'c' 40 | }) 41 | }) 42 | 43 | describe('/:a/b/:c?', function () { 44 | var match = route('/:a/b/:c?') 45 | 46 | it('/a/b/c', function () { 47 | var params = match('/a/b/c') 48 | assert.deepEqual(params, { 49 | a: 'a', 50 | c: 'c' 51 | }) 52 | }) 53 | 54 | it('/a/b', function () { 55 | var params = match('/a/b') 56 | assert.deepEqual(params, { 57 | a: 'a' 58 | }) 59 | }) 60 | }) 61 | 62 | describe('/:a/:b/:c*', function () { 63 | var match = route('/:a/:b/:c*') 64 | 65 | it('/a/b', function () { 66 | var params = match('/a/b') 67 | assert.deepEqual(params, { 68 | a: 'a', 69 | b: 'b' 70 | }) 71 | }) 72 | 73 | it('/a/b/c', function () { 74 | var params = match('/a/b/c') 75 | assert.deepEqual(params, { 76 | a: 'a', 77 | b: 'b', 78 | c: ['c'] 79 | }) 80 | }) 81 | 82 | it('/a/b/c/d', function () { 83 | var params = match('/a/b/c/d') 84 | assert.deepEqual(params, { 85 | a: 'a', 86 | b: 'b', 87 | c: ['c', 'd'] 88 | }) 89 | }) 90 | 91 | it('/a/b/c/d/e', function () { 92 | var params = match('/a/b/c/d/e') 93 | assert.deepEqual(params, { 94 | a: 'a', 95 | b: 'b', 96 | c: ['c', 'd', 'e'] 97 | }) 98 | }) 99 | }) 100 | 101 | describe('/:a/:b/:c+', function () { 102 | var match = route('/:a/:b/:c+') 103 | 104 | it('/a/b', function () { 105 | var params = match('/a/b') 106 | assert.deepEqual(params, false) 107 | }) 108 | 109 | it('/a/b/c', function () { 110 | var params = match('/a/b/c') 111 | assert.deepEqual(params, { 112 | a: 'a', 113 | b: 'b', 114 | c: ['c'] 115 | }) 116 | }) 117 | 118 | it('/a/b/c/d', function () { 119 | var params = match('/a/b/c/d') 120 | assert.deepEqual(params, { 121 | a: 'a', 122 | b: 'b', 123 | c: ['c', 'd'] 124 | }) 125 | }) 126 | 127 | it('/a/b/c/d/e', function () { 128 | var params = match('/a/b/c/d/e') 129 | assert.deepEqual(params, { 130 | a: 'a', 131 | b: 'b', 132 | c: ['c', 'd', 'e'] 133 | }) 134 | }) 135 | }) 136 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 2 | var pathToRegexp = require('path-to-regexp') 3 | var createError = require('http-errors') 4 | 5 | module.exports = function (options) { 6 | options = options || {} 7 | 8 | return function (path) { 9 | var keys = [] 10 | var re = pathToRegexp(path, keys, options) 11 | 12 | return function (pathname, params) { 13 | var m = re.exec(pathname) 14 | if (!m) return false 15 | 16 | params = params || {} 17 | 18 | var key, param 19 | for (var i = 0; i < keys.length; i++) { 20 | key = keys[i] 21 | param = m[i + 1] 22 | if (!param) continue 23 | params[key.name] = decodeParam(param) 24 | if (key.repeat) params[key.name] = params[key.name].split(key.delimiter) 25 | } 26 | 27 | return params 28 | } 29 | } 30 | } 31 | 32 | function decodeParam (param) { 33 | try { 34 | return decodeURIComponent(param) 35 | } catch (_) { 36 | throw createError(400, 'failed to decode param "' + param + '"') 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "path-match", 3 | "description": "wrapper around path-to-regexp for easy route parameters", 4 | "version": "1.2.4", 5 | "author": { 6 | "name": "Jonathan Ong", 7 | "email": "me@jongleberry.com", 8 | "url": "http://jongleberry.com", 9 | "twitter": "https://twitter.com/jongleberry" 10 | }, 11 | "keywords": [ 12 | "route", 13 | "router", 14 | "routing", 15 | "path", 16 | "regex", 17 | "regexp", 18 | "param", 19 | "params" 20 | ], 21 | "license": "MIT", 22 | "repository": "pillarjs/path-match", 23 | "dependencies": { 24 | "http-errors": "~1.4.0", 25 | "path-to-regexp": "^1.0.0" 26 | }, 27 | "devDependencies": { 28 | "codecov": "^3.6.5", 29 | "eslint": "^6.8.0", 30 | "eslint-config-standard": "^14.1.1", 31 | "eslint-plugin-import": "^2.2.0", 32 | "eslint-plugin-node": "^11.1.0", 33 | "eslint-plugin-promise": "^4.2.1", 34 | "eslint-plugin-react": "^7.0.0", 35 | "eslint-plugin-standard": "^4.0.1", 36 | "jest": "^25.3.0" 37 | }, 38 | "scripts": { 39 | "eslint": "eslint . --ignore-path .gitignore", 40 | "test": "jest" 41 | }, 42 | "files": [ 43 | "index.js" 44 | ] 45 | } 46 | --------------------------------------------------------------------------------