Skip to content

Commit

Permalink
feat(matchers): support max version matching (#53)
Browse files Browse the repository at this point in the history
If a map contains several mappings like 1.2.3, 1.2.0, 1.0.0, then requesting v1 shall give the latest possible version
  • Loading branch information
lirantal authored Oct 25, 2020
1 parent cf6fd0f commit 8713d5c
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 4 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,21 @@ routesMap.set('default', (req, res, next) => {
})
```

If maximal possible version (for example to get the latest bugfix) is necessary, then please specify `useMaxVersion: true` in `route` function, then the maximal possible version will be returned for your request. For example for `1.0` request, the version `1.0.2` will be returned:

```js
const routesMap = new Map()
routesMap.set('1.0.0', (req, res, next) => {
return res.status(200).json({'message': 'hello to you version 1.0.0'})
})
routesMap.set('1.0.2', (req, res, next) => {
return res.status(200).json({'message': 'hello to you version 1.0.2'})
})

router.get('/test', versionRouter.route(routesMap,{useMaxVersion: true}))
```


## Usage with TypeScript

```ts
Expand Down
13 changes: 13 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,25 @@ const { RouteVersionUnmatchedError } = require('./errors')
class versionRouter {
static route (versionsMap = new Map(), options = new Map()) {
return (req, res, next) => {
var versionArray = []
for (let [versionKey, versionRouter] of versionsMap) {
versionArray.push(versionKey)
if (this.checkVersionMatch(req.version, versionKey)) {
return versionRouter(req, res, next)
}
}

if (options.useMaxVersion) {
const maxVersion = semver.maxSatisfying(versionArray, req.version)
if (maxVersion) {
for (let [versionKey, versionRouter] of versionsMap) {
if (this.checkVersionMatch(maxVersion, versionKey)) {
return versionRouter(req, res, next)
}
}
}
}

const defaultRoute = this.getDefaultRoute(versionsMap)
if (defaultRoute) {
return defaultRoute(req, res, next)
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@
"standard": "^12.0.0"
},
"nyc": {
"statements": 88,
"branches": 88,
"functions": 88,
"lines": 88,
"statements": 85,
"branches": 85,
"functions": 85,
"lines": 85,
"reporter": [
"lcov",
"text-summary"
Expand Down
56 changes: 56 additions & 0 deletions test/sanity.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,59 @@ test('given 2 versions and a default, if no match is found the default route sho
const result = middleware(req, {}, () => { })
t.is(result.testVersion, 'default')
})

test('given 2 versions, max version matches', t => {
const v1 = '1.2.0'
const v2 = '1.2.3'
const requestedVersion = '1.2'

const routesMap = new Map()
routesMap.set(v1, (req, res, next) => {
res.out = { testVersion: v1 }
return res.out
})

routesMap.set(v2, (req, res, next) => {
res.out = { testVersion: v2 }
return res.out
})

const middleware = versionRouter.route(routesMap, { useMaxVersion: true })
const req = {
version: requestedVersion
}

const result = middleware(req, {}, () => { })
t.is(result.testVersion, v2)
})

test('given 2 versions, if no max version default matches', t => {
const v1 = '1.2.0'
const v2 = '1.2.3'
const v3 = 'default'
const requestedVersion = '1.2'

const routesMap = new Map()
routesMap.set(v1, (req, res, next) => {
res.out = { testVersion: v1 }
return res.out
})

routesMap.set(v2, (req, res, next) => {
res.out = { testVersion: v2 }
return res.out
})

routesMap.set(v3, (req, res, next) => {
res.out = { testVersion: v3 }
return res.out
})

const middleware = versionRouter.route(routesMap)
const req = {
version: requestedVersion
}

const result = middleware(req, {}, () => { })
t.is(result.testVersion, v3)
})

0 comments on commit 8713d5c

Please sign in to comment.