This commit is contained in:
21
node_modules/centra/LICENSE
generated
vendored
Normal file
21
node_modules/centra/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Ethan Davis
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
144
node_modules/centra/README.md
generated
vendored
Normal file
144
node_modules/centra/README.md
generated
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
<p align="center" style="text-align: center;"><img src="https://github.com/ethanent/centra/blob/master/media/centraLogo.png?raw=true" width="400"/></p>
|
||||
|
||||
> The core lightweight HTTP client for Node
|
||||
|
||||
[GitHub](https://github.com/ethanent/centra) | [NPM](https://npmjs.com/package/centra)
|
||||
|
||||
## Install
|
||||
|
||||
```shell
|
||||
npm i centra
|
||||
```
|
||||
|
||||
## Why centra?
|
||||
|
||||
centra is the best request library for developers; it provides a number of extremely useful features while still being one of the most lightweight Node.js HTTP client libraries available.
|
||||
|
||||
## Use centra!
|
||||
|
||||
First, require the library.
|
||||
|
||||
```js
|
||||
const c = require('centra')
|
||||
```
|
||||
|
||||
Then let's make a request in an async function!
|
||||
|
||||
```js
|
||||
;(async () => {
|
||||
const res = await c('https://example.com').send()
|
||||
|
||||
console.log(await res.text())
|
||||
})()
|
||||
```
|
||||
|
||||
## More advanced usage
|
||||
|
||||
### Send data in a JSON body
|
||||
|
||||
```js
|
||||
c('https://example.com/nonexistentJSONAPI', 'POST').body({
|
||||
'name': 'Ethan'
|
||||
}, 'json').send().then((res) => {
|
||||
/*...*/
|
||||
})
|
||||
```
|
||||
|
||||
### Send data in a form body
|
||||
|
||||
```js
|
||||
c('https://example.com/nonexistentJSONAPI', 'POST').body({
|
||||
'name': 'Ethan'
|
||||
}, 'form').send().then((res) => {
|
||||
/*...*/
|
||||
})
|
||||
```
|
||||
|
||||
### Set query string parameters
|
||||
|
||||
One at a time:
|
||||
|
||||
```js
|
||||
c('https://example.com/user').query('id', 'u1817760').send().then((res) => {
|
||||
/*...*/
|
||||
})
|
||||
```
|
||||
|
||||
Many at a time:
|
||||
|
||||
```js
|
||||
c('https://example.com/user').query({
|
||||
'id', 'u1817760',
|
||||
'name': 'Ethan'
|
||||
}).send().then((res) => {
|
||||
/*...*/
|
||||
})
|
||||
```
|
||||
|
||||
### Set a request timeout
|
||||
|
||||
```js
|
||||
c('https://example.com').timeout(2000).send().then((res) => {
|
||||
// Success!
|
||||
}).catch((err) => {
|
||||
// Has the request timed out?
|
||||
})
|
||||
```
|
||||
|
||||
### Stream a request's response
|
||||
|
||||
In this example, the [stream](https://nodejs.org/api/stream.html) is piped to a file:
|
||||
|
||||
```js
|
||||
// require the fs module beforehand
|
||||
|
||||
c('https://example.com').stream().send().then((stream) => stream.pipe(fs.createWriteStream(path.join(__dirname, 'logo.png'))))
|
||||
```
|
||||
|
||||
### Follow redirects
|
||||
|
||||
```js
|
||||
c('https://example.com/').followRedirects(5).send()
|
||||
```
|
||||
|
||||
### Switch paths on the fly
|
||||
|
||||
```js
|
||||
c('https://example.com/test').path('/hello').send()
|
||||
|
||||
// This will make a request to https://example.com/test/hello
|
||||
```
|
||||
|
||||
### Specify request headers
|
||||
|
||||
One at a time:
|
||||
|
||||
```js
|
||||
c('https://example.com').header('Content-Type', 'application/json').send()
|
||||
```
|
||||
|
||||
Many at a time:
|
||||
|
||||
```js
|
||||
c('https://example.com').header({
|
||||
'Content-Type': 'application/json',
|
||||
'X-Connecting-With': 'centra'
|
||||
}).send()
|
||||
```
|
||||
|
||||
### Modify core HTTP request options
|
||||
|
||||
See [http.request](https://nodejs.org/dist/latest-v10.x/docs/api/http.html#http_http_request_url_options_callback)'s options for more information about core HTTP request options.
|
||||
Let's change our localAddress as an example.
|
||||
|
||||
```js
|
||||
c('https://example.com').option('localAddress', '127.0.0.2').send()
|
||||
```
|
||||
|
||||
### Accept compressed responses
|
||||
|
||||
```js
|
||||
c('https://example.com').compress().send()
|
||||
|
||||
// This will cause centra to accept compressed content from the server. (gzip and deflate are currently supported)
|
||||
```
|
||||
5
node_modules/centra/createRequest.js
generated
vendored
Normal file
5
node_modules/centra/createRequest.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
const CentraRequest = require('./model/CentraRequest.js')
|
||||
|
||||
module.exports = (url, method) => {
|
||||
return new CentraRequest(url, method)
|
||||
}
|
||||
220
node_modules/centra/model/CentraRequest.js
generated
vendored
Normal file
220
node_modules/centra/model/CentraRequest.js
generated
vendored
Normal file
@@ -0,0 +1,220 @@
|
||||
const path = require('path')
|
||||
const http = require('http')
|
||||
const https = require('https')
|
||||
const followRedirects = require('follow-redirects')
|
||||
const qs = require('querystring')
|
||||
const zlib = require('zlib')
|
||||
const {URL} = require('url')
|
||||
|
||||
const CentraResponse = require('./CentraResponse.js')
|
||||
|
||||
const supportedCompressions = ['gzip', 'deflate', 'br']
|
||||
|
||||
const useRequest = (protocol, maxRedirects) => {
|
||||
let httpr
|
||||
let httpsr
|
||||
if (maxRedirects <= 0) {
|
||||
httpr = http.request
|
||||
httpsr = https.request
|
||||
}
|
||||
else {
|
||||
httpr = followRedirects.http.request
|
||||
httpsr = followRedirects.https.request
|
||||
}
|
||||
|
||||
if (protocol === 'http:') {
|
||||
return httpr
|
||||
}
|
||||
else if (protocol === 'https:') {
|
||||
return httpsr
|
||||
}
|
||||
else throw new Error('Bad URL protocol: ' + protocol)
|
||||
}
|
||||
|
||||
module.exports = class CentraRequest {
|
||||
constructor (url, method = 'GET') {
|
||||
this.url = typeof url === 'string' ? new URL(url) : url
|
||||
this.method = method
|
||||
this.data = null
|
||||
this.sendDataAs = null
|
||||
this.reqHeaders = {}
|
||||
this.streamEnabled = false
|
||||
this.compressionEnabled = false
|
||||
this.timeoutTime = null
|
||||
this.coreOptions = {}
|
||||
this.maxRedirects = 0
|
||||
|
||||
this.resOptions = {
|
||||
'maxBuffer': 50 * 1000000 // 50 MB
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
followRedirects(n) {
|
||||
this.maxRedirects = n
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
query (a1, a2) {
|
||||
if (typeof a1 === 'object') {
|
||||
Object.keys(a1).forEach((queryKey) => {
|
||||
this.url.searchParams.append(queryKey, a1[queryKey])
|
||||
})
|
||||
}
|
||||
else this.url.searchParams.append(a1, a2)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
path (relativePath) {
|
||||
this.url.pathname = path.join(this.url.pathname, relativePath)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
body (data, sendAs) {
|
||||
this.sendDataAs = typeof data === 'object' && !sendAs && !Buffer.isBuffer(data) ? 'json' : (sendAs ? sendAs.toLowerCase() : 'buffer')
|
||||
this.data = this.sendDataAs === 'form' ? qs.stringify(data) : (this.sendDataAs === 'json' ? JSON.stringify(data) : data)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
header (a1, a2) {
|
||||
if (typeof a1 === 'object') {
|
||||
Object.keys(a1).forEach((headerName) => {
|
||||
this.reqHeaders[headerName.toLowerCase()] = a1[headerName]
|
||||
})
|
||||
}
|
||||
else this.reqHeaders[a1.toLowerCase()] = a2
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
timeout (timeout) {
|
||||
this.timeoutTime = timeout
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
option (name, value) {
|
||||
this.coreOptions[name] = value
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
stream () {
|
||||
this.streamEnabled = true
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
compress () {
|
||||
this.compressionEnabled = true
|
||||
|
||||
if (!this.reqHeaders['accept-encoding']) this.reqHeaders['accept-encoding'] = supportedCompressions.join(', ')
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
send () {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.data) {
|
||||
if (!this.reqHeaders.hasOwnProperty('content-type')) {
|
||||
if (this.sendDataAs === 'json') {
|
||||
this.reqHeaders['content-type'] = 'application/json'
|
||||
}
|
||||
else if (this.sendDataAs === 'form') {
|
||||
this.reqHeaders['content-type'] = 'application/x-www-form-urlencoded'
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.reqHeaders.hasOwnProperty('content-length')) {
|
||||
this.reqHeaders['content-length'] = Buffer.byteLength(this.data)
|
||||
}
|
||||
}
|
||||
|
||||
const options = Object.assign({
|
||||
'protocol': this.url.protocol,
|
||||
'host': this.url.hostname.replace('[', '').replace(']', ''),
|
||||
'port': this.url.port,
|
||||
'path': this.url.pathname + (this.url.search === null ? '' : this.url.search),
|
||||
'method': this.method,
|
||||
'headers': this.reqHeaders,
|
||||
'maxRedirects': this.maxRedirects
|
||||
}, this.coreOptions)
|
||||
|
||||
let req
|
||||
|
||||
const resHandler = (res) => {
|
||||
let stream = res
|
||||
|
||||
if (this.compressionEnabled) {
|
||||
if (res.headers['content-encoding'] === 'gzip') {
|
||||
stream = res.pipe(zlib.createGunzip())
|
||||
}
|
||||
else if (res.headers['content-encoding'] === 'deflate') {
|
||||
stream = res.pipe(zlib.createInflate())
|
||||
}
|
||||
else if (res.headers['content-encoding'] === 'br') {
|
||||
stream = res.pipe(zlib.createBrotliDecompress())
|
||||
}
|
||||
}
|
||||
|
||||
let centraRes
|
||||
|
||||
if (this.streamEnabled) {
|
||||
resolve(stream)
|
||||
}
|
||||
else {
|
||||
centraRes = new CentraResponse(res, this.resOptions)
|
||||
|
||||
stream.on('error', (err) => {
|
||||
reject(err)
|
||||
})
|
||||
|
||||
stream.on('aborted', () => {
|
||||
reject(new Error('Server aborted request'))
|
||||
})
|
||||
|
||||
stream.on('data', (chunk) => {
|
||||
centraRes._addChunk(chunk)
|
||||
|
||||
if (this.resOptions.maxBuffer !== null && centraRes.body.length > this.resOptions.maxBuffer) {
|
||||
stream.destroy()
|
||||
|
||||
reject('Received a response which was longer than acceptable when buffering. (' + this.body.length + ' bytes)')
|
||||
}
|
||||
})
|
||||
|
||||
stream.on('end', () => {
|
||||
resolve(centraRes)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const request = useRequest(this.url.protocol, this.maxRedirects)
|
||||
|
||||
req = request(options, resHandler)
|
||||
|
||||
if (this.timeoutTime) {
|
||||
req.setTimeout(this.timeoutTime, () => {
|
||||
req.abort()
|
||||
|
||||
if (!this.streamEnabled) {
|
||||
reject(new Error('Timeout reached'))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
req.on('error', (err) => {
|
||||
reject(err)
|
||||
})
|
||||
|
||||
if (this.data) req.write(this.data)
|
||||
|
||||
req.end()
|
||||
})
|
||||
}
|
||||
}
|
||||
23
node_modules/centra/model/CentraResponse.js
generated
vendored
Normal file
23
node_modules/centra/model/CentraResponse.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
module.exports = class CentraResponse {
|
||||
constructor (res, resOptions) {
|
||||
this.coreRes = res
|
||||
this.resOptions = resOptions
|
||||
|
||||
this.body = Buffer.alloc(0)
|
||||
|
||||
this.headers = res.headers
|
||||
this.statusCode = res.statusCode
|
||||
}
|
||||
|
||||
_addChunk (chunk) {
|
||||
this.body = Buffer.concat([this.body, chunk])
|
||||
}
|
||||
|
||||
async json () {
|
||||
return this.statusCode === 204 ? null : JSON.parse(this.body)
|
||||
}
|
||||
|
||||
async text () {
|
||||
return this.body.toString()
|
||||
}
|
||||
}
|
||||
40
node_modules/centra/package.json
generated
vendored
Normal file
40
node_modules/centra/package.json
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "centra",
|
||||
"version": "2.7.0",
|
||||
"description": "The core lightweight HTTP client for Node",
|
||||
"main": "createRequest.js",
|
||||
"scripts": {
|
||||
"test": "node test.js --test-force-exit",
|
||||
"prepublishOnly": "npm test"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/ethanent/centra.git"
|
||||
},
|
||||
"files": [
|
||||
"model/CentraRequest.js",
|
||||
"model/CentraResponse.js",
|
||||
"createRequest.js"
|
||||
],
|
||||
"keywords": [
|
||||
"http",
|
||||
"https",
|
||||
"request",
|
||||
"fetch",
|
||||
"url",
|
||||
"lightweight"
|
||||
],
|
||||
"author": "Ethan Davis",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/ethanent/centra/issues"
|
||||
},
|
||||
"homepage": "https://github.com/ethanent/centra",
|
||||
"devDependencies": {
|
||||
"body-parser": "^1.20.2",
|
||||
"express": "^4.19.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user