Skip to content

Commit 18c8ec8

Browse files
authored
Release v2.0.0 (#3)
* - use Object.assign instead of lodash/merge - refactor test config [Fixes] * 1.0.1 * 1.0.2 * feature(release-v2): release v2.0.0
1 parent f07375a commit 18c8ec8

File tree

18 files changed

+240
-216
lines changed

18 files changed

+240
-216
lines changed

.babelrc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
{
2-
"presets": [
3-
"env"
4-
]
2+
"presets": ["env"],
3+
"plugins": ["transform-es2015-destructuring", "transform-object-rest-spread"]
54
}

Readme.md

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ Express API versioning is an express middleware that dynamically loads different
1010

1111
It is written in Javascript ES6 syntax and it is further transpiled down to Javascript ES5 using babel.
1212

13+
# What's new in v2
14+
- Version 2 introduces a new way to resolve errors using callback instead of the `try` and `catch` block.
15+
1316
# Installation
1417

1518
- `npm install express-api-versioning --save`
@@ -23,46 +26,49 @@ It is written in Javascript ES6 syntax and it is further transpiled down to Java
2326
### Using ES5
2427

2528
` const expressApiVersioning = require('express-api-versioning');`
26-
### Basic Usage
2729

2830
```js
2931
app.use(expressApiVersioning({
30-
instance: app, // passes an instance of express to the entry point
31-
apiPath: path.join(__dirname, './api'), // absolute path to the api directory
32-
test: /\/api\/(v[0-9]+).*/, // regular expression to get the version number from the url
33-
entryPoint: 'app.js' // entry point exports a function which takes an instance of express as parameter.
34-
}));
35-
```
36-
### Advanced Usage
37-
38-
```js
39-
app.use(expressApiVersioning({
40-
instance: app, // passes an instance of express to the entry point
41-
apiPath: path.join(__dirname, './api'), // absolute path to the api directory
42-
test: /\/endpoint\/(v[0-9]+).*/, // regular expression to get the version number from the url,
43-
entryPoint: 'index.js' // entry point exports a function which takes an instance of express as parameter.
44-
}));
32+
apiPath: path.join(__dirname, './api'),// absolute path to the api directory
33+
test: /\/api\/(v[0-9]+).*/, // regular expression to get the version number from the url
34+
entryPoint: 'index.js', // entry point exports a function which takes an instance of express as parameter.
35+
instance: app // passes an instance of express to the entry point
36+
}, (error, req, res, next) => {
37+
// Do something here with the error
38+
next(); // calls the next middleware
39+
}));
4540
```
46-
- Check the [src/example](/src/sample) directory to understand the folder structure.
4741

4842
# Error Handling
4943

50-
The middleware will throw an exception when;
44+
As of v2, the middleware returns an error object as the first parameter of the callback and has properties `code` and `message`.
45+
46+
The middleware will throw an error when;
5147
1. the `apiPath` is not specified
5248
1. an express `instance` is not specified and not a function
5349
1. the api version cannot be found in the `api directory`.
5450

51+
# Error Code
52+
53+
| S/N | Code | Message |
54+
| --- | -------- | -------- |
55+
| 1. | 101 | You must explicitly specify a path to where the APIs reside |
56+
| 2. | 102 | You must explicitly set an instance of express |
57+
| 3. | 103 | Entry point not Found |
58+
| 4. | 104 | No version number found |
59+
| 5. | 105 | An instance of express must be a function but got type `${typeof instance}` |
60+
5561
# Issue Reporting
5662

57-
Please use the [issues](/issues) page to report an issue.
63+
Please use the [issues](https://github.com/adesege/express-api-versioning/issues) page to report an issue.
5864

5965
# API References
6066

6167
`Express API Versioning` is highly customizable and does not introduce complexities to your application folder structure. It takes a configuration object as parameter.
6268

6369
| Configuration item | Default | Description |
6470
| ------ | ------ | ------- |
65-
| test | `/\/api\/(v[0-9]+)[a-z0-9/_+-]*/`| Regular expression to get the version number from the request url. It gets the version number from the first group of the regex match.
71+
| test | `/\/api\/(v[0-9]+).*/`| Regular expression to get the version number from the request url. It gets the version number from the first group of the regex match.
6672
| entryPoint | app.js | Entry point for each api version. It exports a function which takes an instance of express as parameter.
6773
| apiPath | empty string | Absolute path to each api version container/directory. This is usually `path.join(__dirname, './api')`.
6874
| instance | null | An instance of express app which will be passed down to the entry point for usage.

package-lock.json

Lines changed: 43 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,19 @@
1212
"url": "https://github.com/adesege/express-api-versioning.git"
1313
},
1414
"scripts": {
15-
"test": "mocha --compilers js:babel-register src/test/**/**.js",
15+
"test": "mocha --compilers js:babel-register src/test/**.spec.js --timeout 100000",
1616
"build": "rm -rf ./build && babel --watch src/ --out-dir build/",
1717
"prepublish": "rm -rf ./build && babel src/ --out-dir build/",
1818
"coveralls": "NODE_ENV=test nyc npm test && nyc report --reporter=lcov --reporter=text --reporter=lcovonly || coveralls"
1919
},
2020
"keywords": [
2121
"express",
2222
"api",
23-
"versioning"
23+
"versioning",
24+
"express api versioning",
25+
"express-api-versioning",
26+
"version",
27+
"expressjs"
2428
],
2529
"author": {
2630
"name": "Fadojutimi Temitayo Olusegun",
@@ -39,6 +43,8 @@
3943
"dependencies": {
4044
"babel-cli": "^6.26.0",
4145
"babel-core": "^6.26.0",
46+
"babel-plugin-transform-es2015-destructuring": "^6.23.0",
47+
"babel-plugin-transform-object-rest-spread": "^6.26.0",
4248
"babel-preset-env": "^1.6.0",
4349
"chai": "^4.1.2",
4450
"express": "^4.15.5",

src/index.js

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import path from 'path';
22
import fs from 'fs';
3-
import { Exception } from './utils/exception';
43

5-
export default (config) => {
4+
export default (config, callback) => {
65
// define default configuration options
76
const defaultConfig = {
87
test: /\/api\/(v[0-9]+).*/,
@@ -11,30 +10,43 @@ export default (config) => {
1110
instance: null
1211
};
1312

14-
// merge default configuration options with user defined config options
15-
const mergedConfig = Object.assign({}, defaultConfig, config);
13+
// merge default configuration options with user defined config options
14+
const mergedConfig = {
15+
...defaultConfig,
16+
...config
17+
};
1618

17-
// get config options from merged configs
19+
// get config options from merged configs
1820
const {
1921
test,
2022
entryPoint,
2123
apiPath,
2224
instance
2325
} = mergedConfig;
2426

25-
if (!apiPath) { // throw exception if the apiPath is not specified
26-
throw new Exception('You must explicitly specify a path to where the APIs reside');
27-
}
27+
return (httpRequest, httpResponse, next) => {
28+
if (!apiPath) { // throw an error if the apiPath is not specified
29+
return callback({
30+
code: 101,
31+
message: 'You must explicitly specify a path to where the APIs reside'
32+
}, httpRequest, httpResponse, next);
33+
}
2834

29-
if (!instance) { // throw an exception if the express instance is undefined
30-
throw new Exception('You must explicitly set an instance of express');
31-
}
35+
if (!instance) { // throw an error if the express instance is undefined
36+
return callback({
37+
code: 102,
38+
message: 'You must explicitly set an instance of express'
39+
}, httpRequest, httpResponse, next);
40+
}
3241

33-
if (typeof instance !== 'function') { // throw an exception if the instance is not a function
34-
throw new Exception(`An instance of express must be a function but got type ${typeof instance}`);
35-
}
42+
if (typeof instance !== 'function') { // throw an error if the instance is not a function
43+
/* istanbul ignore next */
44+
return callback({
45+
code: 105,
46+
message: `An instance of express must be a function but got type ${typeof instance}`
47+
}, httpRequest, httpResponse, next);
48+
}
3649

37-
return (httpRequest, httpResponse, next) => {
3850
// test if the version number/type exist in the url
3951
const testUrl = httpRequest.url.match(test);
4052
const version = testUrl ? testUrl[1] : '';
@@ -43,14 +55,23 @@ export default (config) => {
4355
// normalize path to the entry point
4456
const fullPath = path.normalize(`${apiPath}/${version}/${entryPoint}`);
4557
if (fs.existsSync(fullPath)) { // check if the entry point exist
58+
/* istanbul ignore else */
4659
if (typeof require(fullPath).default === 'function') {
4760
require(fullPath).default(instance); // import the entry point
4861
} else {
4962
require(fullPath)(instance);
5063
}
51-
next();
64+
return callback(null, httpRequest, httpResponse, next);
5265
}
66+
return callback({
67+
code: 103,
68+
message: 'Entry point not Found'
69+
}, httpRequest, httpResponse, next); // we can't find the entry point, throw an error
5370
}
54-
throw new Exception('Not Found');
71+
// we can't find the version number from the url, throw an error
72+
return callback({
73+
code: 104,
74+
message: 'No version number found'
75+
}, httpRequest, httpResponse, next);
5576
};
5677
};

src/sample/advanced/server.js

Lines changed: 0 additions & 14 deletions
This file was deleted.

src/sample/basic/api/v1/routes/index.js

Lines changed: 0 additions & 10 deletions
This file was deleted.

src/sample/basic/server.js

Lines changed: 0 additions & 12 deletions
This file was deleted.

src/test/advanced/index.js

Lines changed: 0 additions & 61 deletions
This file was deleted.

0 commit comments

Comments
 (0)