@autofleet/network 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,26 @@
1
+ version: 2
2
+ jobs:
3
+ test:
4
+ docker:
5
+ - image: circleci/node:8.9.4
6
+ steps:
7
+ - checkout
8
+ - restore_cache:
9
+ keys:
10
+ - v1-dependencies-{{ checksum "package.json" }}
11
+ # fallback to using the latest cache if no exact match is found
12
+ - v1-dependencies-
13
+ - run: npm i
14
+ - save_cache:
15
+ paths:
16
+ - node_modules
17
+ key: v1-dependencies-{{ checksum "package.json" }}
18
+ - run: npm run coverage
19
+ - run: rm -rf ./coverage
20
+ - run: npm run linter
21
+
22
+ workflows:
23
+ version: 2
24
+ build_and_test:
25
+ jobs:
26
+ - test
package/index.js ADDED
@@ -0,0 +1,95 @@
1
+ const axios = require('axios');
2
+ const axiosRetry = require('axios-retry');
3
+ const { Logger } = require('@autofleet/node-common');
4
+ const qs = require('qs');
5
+ const httpAdapter = require('axios/lib/adapters/http');
6
+ require('dotenv').config();
7
+ /**
8
+ * Add support for nock testing
9
+ * see s://github.com/axios/axios/issues/305
10
+ */
11
+ if (process.env.NODE_ENV === 'test') {
12
+ axios.defaults.adapter = httpAdapter;
13
+ }
14
+
15
+ const HTTPMethods = [
16
+ 'get',
17
+ 'post',
18
+ 'delete',
19
+ 'head',
20
+ 'put',
21
+ 'patch',
22
+ 'options',
23
+ ];
24
+
25
+ const defaultSettings = {
26
+ timeout: 2500,
27
+ headers: { 'X-AF-AUTH': 'ANYONE' },
28
+ paramsSerializer: params => qs.stringify(params, { arrayFormat: 'brackets' }),
29
+ };
30
+
31
+ module.exports = class Network {
32
+ constructor(settings = {}) {
33
+ this.settings = Object.assign({}, defaultSettings, settings);
34
+ this.createBaseUrl();
35
+
36
+ this.axios = axios.create(this.settings);
37
+ this.addRetry(settings);
38
+ this.buildClassHttpMethods();
39
+ this.addLogs();
40
+ }
41
+
42
+ addRetry(settings) {
43
+ axiosRetry(this.axios, {
44
+ retries: 0,
45
+ retryDelay: axiosRetry.exponentialDelay,
46
+ ...settings,
47
+ });
48
+ }
49
+
50
+ addLogs() {
51
+ const logger = Logger();
52
+ this.axios.interceptors.request.use((request) => {
53
+ logger.info(`Start Request: [${request.method.toUpperCase()}] ${request.baseURL} ${request.url}`, {
54
+ headers: request.headers,
55
+ query: request.query,
56
+ body: request.body,
57
+ });
58
+ return request;
59
+ });
60
+
61
+ this.axios.interceptors.response.use((response) => {
62
+ logger.info(`Finish Request: [${response.config.method.toUpperCase()} ${response.config.url}`);
63
+ return response;
64
+ }, (error) => {
65
+ logger.error('Finish Request with error', { status: error.status, data: error.response && error.response.data });
66
+ throw error;
67
+ });
68
+ }
69
+
70
+ createBaseUrl() {
71
+ if (!this.settings.serviceUrl && !this.settings.serviceName) {
72
+ throw new Error('At least one of the settings Missing serviceUrl or serviceName');
73
+ }
74
+
75
+ const { settings } = this;
76
+ if (settings.serviceUrl) {
77
+ settings.baseURL = settings.serviceUrl;
78
+ } else if (settings.serviceName) {
79
+ const envServiceHostName = `${settings.serviceName}_SERVICE_HOST`;
80
+ settings.baseURL = `http://${process.env[envServiceHostName]}`;
81
+ if (!settings.baseURL) {
82
+ throw new Error(`Missing environment variable: ${envServiceHostName}`);
83
+ }
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Build class methods that wrap axios methods
89
+ */
90
+ buildClassHttpMethods() {
91
+ HTTPMethods.forEach((method) => {
92
+ this[method] = (...args) => this.axios[method](...args);
93
+ });
94
+ }
95
+ };
package/index.test.js ADDED
@@ -0,0 +1,69 @@
1
+ const nock = require('nock');
2
+ const Network = require('./index');
3
+
4
+ nock('http://www.google.com')
5
+ .get('/resource')
6
+ .reply(200, { one: 1 });
7
+
8
+
9
+ nock('https://www.apple.com')
10
+ .get('/resource')
11
+ .reply(200, { two: 2 });
12
+
13
+ describe('Network', () => {
14
+ it('Making requests by service name from ENV', async () => {
15
+ process.env.TEST_SERVICE_HOST = 'www.google.com';
16
+ const n = new Network({ serviceName: 'TEST' });
17
+ const response = await n.get('/resource');
18
+ expect(response).toBeDefined();
19
+ expect(response.data).toBeDefined();
20
+ expect(response.data.one).toBe(1);
21
+ });
22
+
23
+ it('Making requests by service name from url', async () => {
24
+ const n = new Network({ serviceUrl: 'https://www.apple.com' });
25
+ const response = await n.get('/resource');
26
+ expect(response).toBeDefined();
27
+ expect(response.data).toBeDefined();
28
+ expect(response.data.two).toBe(2);
29
+ });
30
+
31
+ it('Getting 404', async () => {
32
+ const n = new Network({ serviceUrl: 'https://www.apple.com' });
33
+
34
+ const action = async () => n.get('/resource', {
35
+ query: {
36
+ a: 'b',
37
+ },
38
+ });
39
+
40
+ expect(action()).rejects.toThrow(Error);
41
+ });
42
+
43
+ test('Retry 1 time', async () => {
44
+ nock('https://www.apple2.com')
45
+ .get('/resource')
46
+ .once()
47
+ .reply(500);
48
+
49
+
50
+ nock('https://www.apple2.com')
51
+ .get('/resource')
52
+ .once()
53
+ .reply(200, { two: 2 });
54
+
55
+ const n = new Network({ serviceUrl: 'https://www.apple2.com' });
56
+ const response = await n.get('/resource', {
57
+ query: {
58
+ a: 'b',
59
+ },
60
+ 'axios-retry': {
61
+ retries: 1,
62
+ },
63
+ });
64
+
65
+ expect(response).toBeDefined();
66
+ expect(response.data).toBeDefined();
67
+ expect(response.data.two).toBe(2);
68
+ });
69
+ });
package/jest.config.js ADDED
@@ -0,0 +1,8 @@
1
+ module.exports = {
2
+ testEnvironment: 'node',
3
+ coverageThreshold: {
4
+ global: {
5
+ lines: 85,
6
+ },
7
+ },
8
+ };
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@autofleet/network",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "jest --forceExit --runInBand",
8
+ "test-auto": "jest --watch --runInBand",
9
+ "linter": "./node_modules/.bin/eslint ."
10
+ },
11
+ "author": "Dor Shay",
12
+ "license": "ISC",
13
+ "dependencies": {
14
+ "@autofleet/node-common": "^1.1.50",
15
+ "axios": "^0.18.0",
16
+ "axios-retry": "^3.1.1",
17
+ "dotenv": "^6.0.0",
18
+ "qs": "^6.5.2"
19
+ },
20
+ "devDependencies": {
21
+ "jest": "22.4.3",
22
+ "nock": "^10.0.0"
23
+ }
24
+ }