Skip to content

Commit

Permalink
Merge pull request #92 from AlbertoFdzM/support-route-param-regexps
Browse files Browse the repository at this point in the history
Support route param regexps
  • Loading branch information
AlbertoFdzM authored Apr 6, 2024
2 parents 6dbb3ec + d610e44 commit 101d553
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 5 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ on:
push:
branches:
- develop
- main
pull_request:
branches:
- develop
- main
workflow_call:

jobs:
Expand Down
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [UNRELEASED]

###
### Added
- Add support for NodeJS v18 and v20.
- Add support for route param regexps.

### Deprecated
- **BREAKING CHANGE** Drop support for NodeJS v12, v14 and v16.
Expand Down
9 changes: 5 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const regExpToParseExpressPathRegExp = /^\/\^\\\/(?:(:?[\w\\.-]*(?:\\\/:?[\w\\.-]*)*)|(\(\?:\(\[\^\\\/]\+\?\)\)))\\\/.*/
const regExpToReplaceExpressPathRegExpParams = /\(\?:\(\[\^\\\/]\+\?\)\)/
const regexpExpressParamRegexp = /\(\?:\(\[\^\\\/]\+\?\)\)/g
const regExpToParseExpressPathRegExp = /^\/\^\\\/(?:(:?[\w\\.-]*(?:\\\/:?[\w\\.-]*)*)|(\(\?:\([^)]+\)\)))\\\/.*/
const regExpToReplaceExpressPathRegExpParams = /\(\?:\([^)]+\)\)/
const regexpExpressParamRegexp = /\(\?:\([^)]+\)\)/g
const regexpExpressPathParamRegexp = /(:[^)]+)\([^)]+\)/g

const EXPRESS_ROOT_PATH_REGEXP_VALUE = '/^\\/?(?=\\/|$)/i'
const STACK_ITEM_VALID_NAMES = [
Expand Down Expand Up @@ -62,7 +63,7 @@ const parseExpressRoute = function (route, basePath) {
: `${basePath}${path}`

const endpoint = {
path: completePath,
path: completePath.replace(regexpExpressPathParamRegexp, '$1'),
methods: getRouteMethods(route),
middlewares: getRouteMiddlewares(route)
}
Expand Down
114 changes: 114 additions & 0 deletions test/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -598,4 +598,118 @@ describe('express-list-endpoints', () => {
expect(endpoints[1].middlewares).to.have.length(0)
})
})

describe('supports regexp validators for params', () => {
let endpoints

before(() => {
const app = express()

app.get('/foo/:item_id(\\d+)/bar', (req, res) => {
res.end()
})

endpoints = listEndpoints(app)
})

it('should list routes correctly', () => {
expect(endpoints).to.have.length(1)
expect(endpoints[0].path).to.be.equal('/foo/:item_id/bar')
expect(endpoints[0].methods[0]).to.be.equal('GET')
expect(endpoints[0].middlewares[0]).to.be.equal('anonymous')
})
})

describe('supports multiple regexp validators for params', () => {
let endpoints

before(() => {
const app = express()

app.get('/foo/bar/:baz_id(\\d+)/:biz_id(\\d+)', (req, res) => {
res.end()
})

endpoints = listEndpoints(app)
})

it('should list routes correctly', () => {
expect(endpoints).to.have.length(1)
expect(endpoints[0].path).to.be.equal('/foo/bar/:baz_id/:biz_id')
expect(endpoints[0].methods[0]).to.be.equal('GET')
expect(endpoints[0].middlewares[0]).to.be.equal('anonymous')
})
})

describe('supports regexp validators for params with subapp', () => {
let endpoints

before(() => {
const app = express()
const subApp = express.Router()

subApp.get('/baz', (req, res) => {
res.end()
})

app.use('/foo/:item_id(\\d+)/bar', subApp)

endpoints = listEndpoints(app)
})

it('should list routes correctly', () => {
expect(endpoints).to.have.length(1)
expect(endpoints[0].path).to.be.equal('/foo/:item_id/bar/baz')
expect(endpoints[0].methods[0]).to.be.equal('GET')
expect(endpoints[0].middlewares[0]).to.be.equal('anonymous')
})
})

describe('supports regexp validators for params in subapp', () => {
let endpoints

before(() => {
const app = express()
const subApp = express.Router()

subApp.get('/baz/:biz_id(\\d+)', (req, res) => {
res.end()
})

app.use('/foo/bar', subApp)

endpoints = listEndpoints(app)
})

it('should list routes correctly', () => {
expect(endpoints).to.have.length(1)
expect(endpoints[0].path).to.be.equal('/foo/bar/baz/:biz_id')
expect(endpoints[0].methods[0]).to.be.equal('GET')
expect(endpoints[0].middlewares[0]).to.be.equal('anonymous')
})
})

describe('supports multiple regexp validators for params in subapp', () => {
let endpoints

before(() => {
const app = express()
const subApp = express.Router()

subApp.get('/bar/:baz_id(\\d+)/:biz_id(\\d+)', (req, res) => {
res.end()
})

app.use('/foo', subApp)

endpoints = listEndpoints(app)
})

it('should list routes correctly', () => {
expect(endpoints).to.have.length(1)
expect(endpoints[0].path).to.be.equal('/foo/bar/:baz_id/:biz_id')
expect(endpoints[0].methods[0]).to.be.equal('GET')
expect(endpoints[0].middlewares[0]).to.be.equal('anonymous')
})
})
})

0 comments on commit 101d553

Please sign in to comment.