Skip to content

Commit fa64e16

Browse files
authored
feat: add proxy support (#14)
1 parent ce565ee commit fa64e16

16 files changed

+1325
-465
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ launch.json
55
package-lock.json
66
/node_modules/
77
junit.xml
8+
test-report.html

README.md

Lines changed: 145 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
Copyright 2019 Adobe. All rights reserved.
2+
Copyright 2021 Adobe. All rights reserved.
33
This file is licensed to you under the Apache License, Version 2.0 (the "License");
44
you may not use this file except in compliance with the License. You may obtain a copy
55
of the License at http://www.apache.org/licenses/LICENSE-2.0
@@ -10,12 +10,20 @@ OF ANY KIND, either express or implied. See the License for the specific languag
1010
governing permissions and limitations under the License.
1111
-->
1212

13+
<!--
14+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
15+
DO NOT update README.md, it is generated.
16+
Modify 'docs/readme_template.md', then run `npm run generate-docs`.
17+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
18+
-->
19+
1320
[![Version](https://img.shields.io/npm/v/@adobe/aio-lib-core-networking.svg)](https://npmjs.org/package/@adobe/aio-lib-core-networking)
1421
[![Downloads/week](https://img.shields.io/npm/dw/@adobe/aio-lib-core-networking.svg)](https://npmjs.org/package/@adobe/aio-lib-core-networking)
1522
[![Node.js CI](https://github.com/adobe/aio-lib-core-networking/actions/workflows/node.js.yml/badge.svg)](https://github.com/adobe/aio-lib-core-networking/actions/workflows/node.js.yml)
1623
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
1724
[![Codecov Coverage](https://img.shields.io/codecov/c/github/adobe/aio-lib-core-networking/master.svg?style=flat-square)](https://codecov.io/gh/adobe/aio-lib-core-networking/)
1825

26+
1927
# Adobe I/O Core Networking Lib
2028

2129
### Installing
@@ -28,15 +36,17 @@ $ npm install @adobe/aio-lib-core-networking
2836
1) Initialize the SDK
2937

3038
```javascript
31-
const fetchRetry = require('@adobe/aio-lib-core-networking')
32-
39+
const { HttpExponentialBackoff, createFetch } = require('@adobe/aio-lib-core-networking')
40+
const fetchRetry = new HttpExponentialBackoff()
41+
const proxyFetch = createFetch()
3342
```
3443

3544
2) Call methods using the initialized SDK
3645

3746
```javascript
3847

39-
const fetchRetry = require('@adobe/aio-lib-core-networking')
48+
const { HttpExponentialBackoff, createFetch } = require('@adobe/aio-lib-core-networking')
49+
const fetchRetry = new HttpExponentialBackoff()
4050
async function sdkTest() {
4151

4252
return new Promise((resolve, reject) => {
@@ -54,44 +64,154 @@ async function sdkTest() {
5464
})
5565
}
5666

57-
```
58-
59-
<a name="module_@adobe/aio-lib-core-networking"></a>
60-
61-
## @adobe/aio-lib-core-networking
62-
63-
* [@adobe/aio-lib-core-networking](#module_@adobe/aio-lib-core-networking)
64-
* [~HttpExponentialBackoff](#module_@adobe/aio-lib-core-networking..HttpExponentialBackoff)
65-
* [.exponentialBackoff(url, requestOptions, retryOptions, retryOn, retryDelay)](#module_@adobe/aio-lib-core-networking..HttpExponentialBackoff+exponentialBackoff) ⇒ <code>Promise.&lt;Response&gt;</code>
67+
let proxyFetch
68+
// this will get the proxy settings from the the HTTP_PROXY or HTTPS_PROXY environment variables, if set
69+
proxyFetch = createFetch()
6670

67-
<a name="module_@adobe/aio-lib-core-networking..HttpExponentialBackoff"></a>
71+
// this will use the passed in proxy settings. Embed basic auth in the url, if required
72+
proxyFetch = createFetch({ proxyUrl: 'http://my.proxy:8080' })
6873

69-
### Working of HttpExponentialBackoff
74+
// if the proxy settings are not passed in, and not available in the HTTP_PROXY or HTTPS_PROXY environment variables, it falls back to a simple fetch
75+
const simpleFetch = createFetch()
76+
```
7077

71-
![image not available](docs/sequenceDiagram.jpeg?s=50)
78+
## Classes
7279

73-
### @adobe/aio-lib-core-networking~HttpExponentialBackoff
80+
<dl>
81+
<dt><a href="#HttpExponentialBackoff">HttpExponentialBackoff</a></dt>
82+
<dd><p>This class provides methods to implement fetch with retries.
83+
The retries use exponential backoff strategy
84+
with defaults set to max of 3 retries and initial Delay as 100ms</p>
85+
</dd>
86+
<dt><a href="#ProxyFetch">ProxyFetch</a></dt>
87+
<dd><p>This provides a wrapper for fetch that facilitates proxy auth authorization.</p>
88+
</dd>
89+
</dl>
90+
91+
## Functions
92+
93+
<dl>
94+
<dt><a href="#createFetch">createFetch([proxyAuthOptions])</a> ⇒ <code>function</code></dt>
95+
<dd><p>Return the appropriate Fetch function depending on proxy settings.</p>
96+
</dd>
97+
</dl>
98+
99+
## Typedefs
100+
101+
<dl>
102+
<dt><a href="#RetryOptions">RetryOptions</a> : <code>object</code></dt>
103+
<dd><p>Fetch Retry Options</p>
104+
</dd>
105+
<dt><a href="#ProxyAuthOptions">ProxyAuthOptions</a> : <code>object</code></dt>
106+
<dd><p>Proxy Auth Options</p>
107+
</dd>
108+
</dl>
109+
110+
<a name="HttpExponentialBackoff"></a>
111+
112+
## HttpExponentialBackoff
74113
This class provides methods to implement fetch with retries.
75114
The retries use exponential backoff strategy
76115
with defaults set to max of 3 retries and initial Delay as 100ms
77116

78-
**Kind**: inner class of [<code>@adobe/aio-lib-core-networking</code>](#module_@adobe/aio-lib-core-networking)
79-
<a name="module_@adobe/aio-lib-core-networking..HttpExponentialBackoff+exponentialBackoff"></a>
117+
**Kind**: global class
118+
<a name="HttpExponentialBackoff+exponentialBackoff"></a>
80119

81-
#### httpExponentialBackoff.exponentialBackoff(url, requestOptions, retryOptions, retryOn, retryDelay) ⇒ <code>Promise.&lt;Response&gt;</code>
120+
### httpExponentialBackoff.exponentialBackoff(url, requestOptions, [retryOptions], [retryOn], [retryDelay]) ⇒ <code>Promise.&lt;Response&gt;</code>
82121
This function will retry connecting to a url end-point, with
83122
exponential backoff. Returns a Promise.
84123

85-
**Kind**: instance method of [<code>HttpExponentialBackoff</code>](#module_@adobe/aio-lib-core-networking..HttpExponentialBackoff)
124+
**Kind**: instance method of [<code>HttpExponentialBackoff</code>](#HttpExponentialBackoff)
86125
**Returns**: <code>Promise.&lt;Response&gt;</code> - Promise object representing the http response
87126

88127
| Param | Type | Description |
89128
| --- | --- | --- |
90129
| url | <code>string</code> | endpoint url |
91-
| requestOptions | <code>object</code> | request options which includes the HTTP method, headers, timeout, etc. |
92-
| retryOptions | <code>object</code> | retry options with options being maxRetries and initialDelayInMillis |
93-
| retryOn | <code>function</code> \| <code>Array</code> | Optional Function or Array. If provided, will be used instead of the default |
94-
| retryDelay | <code>function</code> \| <code>number</code> | Optional Function or number. If provided, will be used instead of the default |
130+
| requestOptions | <code>object</code> \| <code>Request</code> | request options |
131+
| [retryOptions] | [<code>RetryOptions</code>](#RetryOptions) | (optional) retry options |
132+
| [retryOn] | <code>function</code> \| <code>Array</code> | (optional) Function or Array. If provided, will be used instead of the default |
133+
| [retryDelay] | <code>function</code> \| <code>number</code> | (optional) Function or number. If provided, will be used instead of the default |
134+
135+
<a name="ProxyFetch"></a>
136+
137+
## ProxyFetch
138+
This provides a wrapper for fetch that facilitates proxy auth authorization.
139+
140+
**Kind**: global class
141+
142+
* [ProxyFetch](#ProxyFetch)
143+
* [new ProxyFetch(authOptions)](#new_ProxyFetch_new)
144+
* [.proxyAgent()](#ProxyFetch+proxyAgent) ⇒ <code>http.Agent</code>
145+
* [.fetch(resource, options)](#ProxyFetch+fetch) ⇒ <code>Promise.&lt;Response&gt;</code>
146+
147+
<a name="new_ProxyFetch_new"></a>
148+
149+
### new ProxyFetch(authOptions)
150+
Initialize this class with Proxy auth options
151+
152+
153+
| Param | Type | Description |
154+
| --- | --- | --- |
155+
| authOptions | [<code>ProxyAuthOptions</code>](#ProxyAuthOptions) | the auth options to connect with |
156+
157+
<a name="ProxyFetch+proxyAgent"></a>
158+
159+
### proxyFetch.proxyAgent() ⇒ <code>http.Agent</code>
160+
Returns the http.Agent used for this proxy
161+
162+
**Kind**: instance method of [<code>ProxyFetch</code>](#ProxyFetch)
163+
**Returns**: <code>http.Agent</code> - a http.Agent for basic auth proxy
164+
<a name="ProxyFetch+fetch"></a>
165+
166+
### proxyFetch.fetch(resource, options) ⇒ <code>Promise.&lt;Response&gt;</code>
167+
Fetch function, using the configured NTLM Auth options.
168+
169+
**Kind**: instance method of [<code>ProxyFetch</code>](#ProxyFetch)
170+
**Returns**: <code>Promise.&lt;Response&gt;</code> - Promise object representing the http response
171+
172+
| Param | Type | Description |
173+
| --- | --- | --- |
174+
| resource | <code>string</code> \| <code>Request</code> | the url or Request object to fetch from |
175+
| options | <code>object</code> | the fetch options |
176+
177+
<a name="createFetch"></a>
178+
179+
## createFetch([proxyAuthOptions]) ⇒ <code>function</code>
180+
Return the appropriate Fetch function depending on proxy settings.
181+
182+
**Kind**: global function
183+
**Returns**: <code>function</code> - the Fetch API function
184+
185+
| Param | Type | Description |
186+
| --- | --- | --- |
187+
| [proxyAuthOptions] | [<code>ProxyAuthOptions</code>](#ProxyAuthOptions) | the proxy auth options |
188+
189+
<a name="RetryOptions"></a>
190+
191+
## RetryOptions : <code>object</code>
192+
Fetch Retry Options
193+
194+
**Kind**: global typedef
195+
**Properties**
196+
197+
| Name | Type | Description |
198+
| --- | --- | --- |
199+
| maxRetries | <code>number</code> | the maximum number of retries to try (default:3) |
200+
| initialDelayInMillis | <code>number</code> | the initial delay in milliseconds (default:100ms) |
201+
| proxy | [<code>ProxyAuthOptions</code>](#ProxyAuthOptions) | the (optional) proxy auth options |
202+
203+
<a name="ProxyAuthOptions"></a>
204+
205+
## ProxyAuthOptions : <code>object</code>
206+
Proxy Auth Options
207+
208+
**Kind**: global typedef
209+
**Properties**
210+
211+
| Name | Type | Description |
212+
| --- | --- | --- |
213+
| proxyUrl | <code>string</code> | the proxy's url |
214+
| rejectUnauthorized | <code>boolean</code> | set to false to not reject unauthorized server certs |
95215

96216
### Debug Logs
97217

docs/readme_template.md

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
Copyright 2019 Adobe. All rights reserved.
2+
Copyright 2021 Adobe. All rights reserved.
33
This file is licensed to you under the Apache License, Version 2.0 (the "License");
44
you may not use this file except in compliance with the License. You may obtain a copy
55
of the License at http://www.apache.org/licenses/LICENSE-2.0
@@ -10,13 +10,21 @@ OF ANY KIND, either express or implied. See the License for the specific languag
1010
governing permissions and limitations under the License.
1111
-->
1212

13-
[![Version](https://img.shields.io/npm/v/@CNA/aio-lib-core-networking.svg)](https://npmjs.org/package/@CNA/aio-lib-core-networking)
14-
[![Downloads/week](https://img.shields.io/npm/dw/@CNA/aio-lib-core-networking.svg)](https://npmjs.org/package/@CNA/aio-lib-core-networking)
15-
[![Build Status](https://travis-ci.com/CNA/aio-lib-core-networking.svg?branch=master)](https://travis-ci.com/CNA/aio-lib-core-networking)
16-
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![Greenkeeper badge](https://badges.greenkeeper.io/CNA/aio-lib-core-networking.svg)](https://greenkeeper.io/)
17-
[![Codecov Coverage](https://img.shields.io/codecov/c/github/CNA/aio-lib-core-networking/master.svg?style=flat-square)](https://codecov.io/gh/CNA/aio-lib-core-networking/)
13+
<!--
14+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
15+
DO NOT update README.md, it is generated.
16+
Modify 'docs/readme_template.md', then run `npm run generate-docs`.
17+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
18+
-->
19+
20+
[![Version](https://img.shields.io/npm/v/@adobe/aio-lib-core-networking.svg)](https://npmjs.org/package/@adobe/aio-lib-core-networking)
21+
[![Downloads/week](https://img.shields.io/npm/dw/@adobe/aio-lib-core-networking.svg)](https://npmjs.org/package/@adobe/aio-lib-core-networking)
22+
[![Node.js CI](https://github.com/adobe/aio-lib-core-networking/actions/workflows/node.js.yml/badge.svg)](https://github.com/adobe/aio-lib-core-networking/actions/workflows/node.js.yml)
23+
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
24+
[![Codecov Coverage](https://img.shields.io/codecov/c/github/adobe/aio-lib-core-networking/master.svg?style=flat-square)](https://codecov.io/gh/adobe/aio-lib-core-networking/)
1825

19-
# Adobe I/O ??? Lib
26+
27+
# Adobe I/O Core Networking Lib
2028

2129
### Installing
2230

@@ -28,39 +36,48 @@ $ npm install @adobe/aio-lib-core-networking
2836
1) Initialize the SDK
2937

3038
```javascript
31-
const sdk = require('@adobe/aio-lib-core-networking')
32-
33-
async function sdkTest() {
34-
//initialize sdk
35-
const client = await sdk.init('<tenant>', 'x-api-key', '<valid auth token>')
36-
}
39+
const { HttpExponentialBackoff, createFetch } = require('@adobe/aio-lib-core-networking')
40+
const fetchRetry = new HttpExponentialBackoff()
41+
const proxyFetch = createFetch()
3742
```
3843

3944
2) Call methods using the initialized SDK
4045

4146
```javascript
42-
const sdk = require('@adobe/aio-lib-core-networking')
4347

48+
const { HttpExponentialBackoff, createFetch } = require('@adobe/aio-lib-core-networking')
49+
const fetchRetry = new HttpExponentialBackoff()
4450
async function sdkTest() {
45-
// initialize sdk
46-
const client = await sdk.init('<tenant>', 'x-api-key', '<valid auth token>')
47-
48-
// call methods
49-
try {
50-
// get profiles by custom filters
51-
const result = await client.getSomething({})
52-
console.log(result)
53-
54-
} catch (e) {
55-
console.error(e)
56-
}
51+
52+
return new Promise((resolve, reject) => {
53+
fetchRetry.exponentialBackoff(url, requestOptions, retryOptions, retryOn, retryDelay)
54+
.then((response) => {
55+
if (!response.ok) {
56+
throw Error(reduceError(response))
57+
}
58+
resolve(response.json())
59+
})
60+
.catch(err => {
61+
reject(
62+
new codes.ERROR_GET_SOMETHING({ sdkDetails, messageValues: err }))
63+
})
64+
})
5765
}
66+
67+
let proxyFetch
68+
// this will get the proxy settings from the the HTTP_PROXY or HTTPS_PROXY environment variables, if set
69+
proxyFetch = createFetch()
70+
71+
// this will use the passed in proxy settings. Embed basic auth in the url, if required
72+
proxyFetch = createFetch({ proxyUrl: 'http://my.proxy:8080' })
73+
74+
// if the proxy settings are not passed in, and not available in the HTTP_PROXY or HTTPS_PROXY environment variables, it falls back to a simple fetch
75+
const simpleFetch = createFetch()
5876
```
5977

6078
{{>main-index~}}
6179
{{>all-docs~}}
6280

63-
6481
### Debug Logs
6582

6683
```bash

package.json

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,19 @@
44
},
55
"bundleDependencies": false,
66
"dependencies": {
7-
"node-fetch": "^2.6.0",
7+
"@adobe/aio-lib-core-config": "^2.0.1",
88
"@adobe/aio-lib-core-errors": "^3.0.0",
99
"@adobe/aio-lib-core-logging": "1.1.0",
10-
"fetch-retry": "^3.0.1"
10+
"fetch-retry": "^3.0.1",
11+
"http-proxy-agent": "^4.0.1",
12+
"https-proxy-agent": "2.2.4",
13+
"node-fetch": "^2.6.4",
14+
"proxy-from-env": "^1.1.0"
1115
},
1216
"deprecated": false,
1317
"description": "Adobe I/O Lib Core Networking",
1418
"devDependencies": {
19+
"@adobe/aio-lib-test-proxy": "^1.0.0",
1520
"@adobe/eslint-config-aio-lib-config": "^1.2.0",
1621
"babel-runtime": "^6.26.0",
1722
"dotenv": "^8.1.0",
@@ -24,16 +29,18 @@
2429
"eslint-plugin-node": "^11.0.0",
2530
"eslint-plugin-promise": "^4.2.1",
2631
"eslint-plugin-standard": "^4.0.0",
32+
"fetch-mock": "^9.0.0",
2733
"jest": "^25.1.0",
2834
"jest-fetch-mock": "^3.0.1",
35+
"jest-html-reporter": "^3.4.1",
2936
"jest-junit": "^10.0.0",
3037
"jest-plugin-fs": "^2.9.0",
3138
"jsdoc": "^3.6.3",
3239
"jsdoc-to-markdown": "^5.0.0",
3340
"openapi-schema-validator": "^3.0.3",
41+
"query-string": "^7.0.1",
3442
"stdout-stderr": "^0.1.9",
35-
"tsd-jsdoc": "^2.4.0",
36-
"fetch-mock": "^9.0.0"
43+
"tsd-jsdoc": "^2.4.0"
3744
},
3845
"homepage": "https://github.com/adobe/aio-lib-core-networking",
3946
"license": "Apache-2.0",
@@ -47,7 +54,11 @@
4754
"lint": "eslint src test",
4855
"test": "npm run lint && npm run unit-tests",
4956
"typings": "jsdoc -t node_modules/tsd-jsdoc/dist -r src/*.js -d .",
50-
"unit-tests": "jest --config test/jest.config.js --maxWorkers=2"
57+
"unit-tests": "jest --config test/jest.config.js --runInBand"
5158
},
52-
"version": "1.0.1"
59+
"version": "1.0.1",
60+
"engineStrict": true,
61+
"engines": {
62+
"node": ">=12.0.0"
63+
}
5364
}

0 commit comments

Comments
 (0)