You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by gl...@apache.org on 2020/02/27 16:09:55 UTC
[couchdb-nano] 01/12: stash changes
This is an automated email from the ASF dual-hosted git repository.
glynnbird pushed a commit to branch axios
in repository https://gitbox.apache.org/repos/asf/couchdb-nano.git
commit 07b4e63ead16aea281b3381bf8a08e650deffbb8
Author: Glynn Bird <gl...@gmail.com>
AuthorDate: Thu Feb 13 10:18:27 2020 +0000
stash changes
---
lib/nano.js | 184 ++++++++++++++++++++++++++++++++----------------------
package-lock.json | 82 ++++++++++++------------
package.json | 6 +-
3 files changed, 152 insertions(+), 120 deletions(-)
diff --git a/lib/nano.js b/lib/nano.js
index b4cc0d0..c77f040 100644
--- a/lib/nano.js
+++ b/lib/nano.js
@@ -12,12 +12,13 @@
const URL = require('url').URL
const assert = require('assert')
-const querystring = require('querystring')
-const request = require('request')
+const querystring = require('qs')
+const axios = require('axios').default
const errs = require('errs')
const follow = require('cloudant-follow')
const logger = require('./logger')
const INVALID_PARAMETERS_ERROR = new Error('Invalid parameters')
+const stream = require('stream')
function isEmpty (val) {
return val == null || !(Object.keys(val) || val).length
@@ -51,8 +52,6 @@ module.exports = exports = function dbScope (cfg) {
serverScope.config = cfg
cfg.requestDefaults = cfg.requestDefaults || {}
- const httpAgent = (typeof cfg.request === 'function') ? cfg.request
- : request.defaults(cfg.requestDefaults)
const followAgent = (typeof cfg.follow === 'function') ? cfg.follow : follow
const log = typeof cfg.log === 'function' ? cfg.log : logger(cfg)
const parseUrl = 'parseUrl' in cfg ? cfg.parseUrl : true
@@ -79,85 +78,89 @@ module.exports = exports = function dbScope (cfg) {
}
return str
}
- const responseHandler = function (req, opts, resolve, reject, callback) {
- return function (err, response = { statusCode: 500 }, body = '') {
- let parsed
- const responseHeaders = Object.assign({
- uri: req.uri,
- statusCode: response.statusCode
- }, response.headers)
- if (err) {
- log({ err: 'socket', body: body, headers: responseHeaders })
- const returnError = errs.merge(err, {
+ const responseHandler = function (response, req, opts, resolve, reject, callback) {
+ if (response.isAxiosError && response.response) {
+ response = response.response
+ }
+ let body = response.data
+ response.statusCode = response.status
+
+ // let parsed
+ const responseHeaders = Object.assign({
+ uri: req.url,
+ statusCode: response.statusCode
+ }, response.headers)
+ if (!response.status) {
+ log({ err: 'socket', body: body, headers: responseHeaders })
+ if (reject) {
+ reject(new Error('error happened in your connection'))
+ }
+ if (callback) {
+ const returnError = {
message: 'error happened in your connection',
scope: 'socket',
errid: 'request'
- })
- if (reject) {
- reject(returnError)
- }
- if (callback) {
- callback(returnError)
}
- return
+ callback(returnError)
}
+ return
+ }
- delete responseHeaders.server
- delete responseHeaders['content-length']
+ delete responseHeaders.server
+ delete responseHeaders['content-length']
- if (opts.dontParse) {
- parsed = body
- } else {
- try { parsed = JSON.parse(body) } catch (err) { parsed = body }
- }
+ /* if (opts.dontParse) {
+ parsed = body
+ } else {
+ try { parsed = JSON.parse(body) } catch (err) { parsed = body }
+ } */
- if (responseHeaders.statusCode >= 200 && responseHeaders.statusCode < 400) {
- log({ err: null, body: parsed, headers: responseHeaders })
- if (resolve) {
- resolve(parsed)
- }
- if (callback) {
- callback(null, parsed, responseHeaders)
- }
- return
+ if (responseHeaders.statusCode >= 200 && responseHeaders.statusCode < 400) {
+ log({ err: null, body: body, headers: responseHeaders })
+ if (resolve) {
+ resolve(body)
}
+ if (callback) {
+ callback(null, body, responseHeaders)
+ }
+ return
+ }
- log({ err: 'couch', body: parsed, headers: responseHeaders })
+ log({ err: 'couch', body: body, headers: responseHeaders })
- // cloudant stacktrace
- if (typeof parsed === 'string') {
- parsed = { message: parsed }
- }
+ // cloudant stacktrace
+ if (typeof body === 'string') {
+ body = { message: body }
+ }
- if (!parsed.message && (parsed.reason || parsed.error)) {
- parsed.message = (parsed.reason || parsed.error)
- }
+ if (!body.message && (body.reason || body.error)) {
+ body.message = (body.reason || body.error)
+ }
- // fix cloudant issues where they give an erlang stacktrace as js
- delete parsed.stack
+ // fix cloudant issues where they give an erlang stacktrace as js
+ delete body.stack
- // scrub credentials
- req.uri = scrub(req.uri)
- responseHeaders.uri = scrub(responseHeaders.uri)
- if (req.headers.cookie) {
- req.headers.cookie = 'XXXXXXX'
- }
+ // scrub credentials
+ req.url = scrub(req.url)
+ responseHeaders.url = scrub(responseHeaders.url)
+ if (req.headers.cookie) {
+ req.headers.cookie = 'XXXXXXX'
+ }
- const errors = errs.merge({
- message: 'couch returned ' + responseHeaders.statusCode,
- scope: 'couch',
- statusCode: responseHeaders.statusCode,
- request: req,
- headers: responseHeaders,
- errid: 'non_200'
- }, errs.create(parsed))
+ const errors = errs.merge({
+ message: 'couch returned ' + req.statusCode,
+ scope: 'couch',
+ statusCode: req.statusCode,
+ request: req,
+ headers: responseHeaders,
+ errid: 'non_200'
+ }, errs.create(body))
- if (reject) {
- reject(errors)
- }
- if (callback) {
- callback(errors)
- }
+ if (reject) {
+ reject(errors)
+ }
+ if (callback) {
+ callback(errors)
}
}
@@ -183,11 +186,11 @@ module.exports = exports = function dbScope (cfg) {
accept: 'application/json'
}
- const req = {
+ const req = Object.assign({
method: (opts.method || 'GET'),
headers: headers,
uri: cfg.url
- }
+ }, cfg.requestDefaults)
// https://github.com/mikeal/request#requestjar
const isJar = opts.jar || cfg.jar
@@ -283,17 +286,46 @@ module.exports = exports = function dbScope (cfg) {
log(req)
+ // This where the HTTP request is made.
+ // Nano used to use the now-deprecated "request" library but now we're going to
+ // use axios, so let's modify the "req" object to suit axios
+ req.url = req.uri
+ delete req.uri
+ req.method = req.method.toLowerCase()
+ req.params = req.qs
+ delete req.qs
+ req.paramsSerializer = (params) => {
+ return querystring.stringify(params, { arrayFormat: 'brackets' })
+ }
+ req.data = req.body
+ delete req.body
+ req.maxRedirects = 0
+ if (opts.stream) {
+ req.responseType = 'stream'
+ } else if (opts.dontParse) {
+ req.responseType = 'arraybuffer'
+ }
+
+ // actually do the HTTP request
if (opts.stream) {
// return the Request object for streaming
- return httpAgent(req)
+ const outStream = new stream.PassThrough()
+ axios(req).then((response) => { response.data.pipe(outStream) })
+ return outStream
} else {
if (typeof callback === 'function') {
- // return nothing - feedback via the callback function
- httpAgent(req, responseHandler(req, opts, null, null, callback))
+ axios(req).then((response) => {
+ responseHandler(response, req, opts, null, null, callback)
+ }).catch((e) => {
+ responseHandler(e, req, opts, null, null, callback)
+ })
} else {
- // return a Promise
- return new Promise(function (resolve, reject) {
- httpAgent(req, responseHandler(req, opts, resolve, reject))
+ return new Promise((resolve, reject) => {
+ axios(req).then((response) => {
+ responseHandler(response, req, opts, resolve, reject)
+ }).catch((e) => {
+ responseHandler(e, req, opts, resolve, reject)
+ })
})
}
}
@@ -422,7 +454,7 @@ module.exports = exports = function dbScope (cfg) {
function followDb (dbName, qs0, callback0) {
const { opts, callback } = getCallback(qs0, callback0)
opts.db = urlResolveFix(cfg.url, encodeURIComponent(dbName))
- opts.httpAgent = httpAgent
+ // opts.httpAgent = httpAgent
if (typeof callback === 'function') {
return followAgent(opts, callback)
} else {
diff --git a/package-lock.json b/package-lock.json
index 18f6963..39a6004 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -937,11 +937,6 @@
"@babel/types": "^7.3.0"
}
},
- "@types/caseless": {
- "version": "0.12.2",
- "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz",
- "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w=="
- },
"@types/color-name": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
@@ -973,45 +968,12 @@
"@types/istanbul-lib-report": "*"
}
},
- "@types/node": {
- "version": "13.7.0",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.0.tgz",
- "integrity": "sha512-GnZbirvmqZUzMgkFn70c74OQpTTUcCzlhQliTzYjQMqg+hVKcDnxdL19Ne3UdYzdMA/+W3eb646FWn/ZaT1NfQ=="
- },
- "@types/request": {
- "version": "2.48.4",
- "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.4.tgz",
- "integrity": "sha512-W1t1MTKYR8PxICH+A4HgEIPuAC3sbljoEVfyZbeFJJDbr30guDspJri2XOaM2E+Un7ZjrihaDi7cf6fPa2tbgw==",
- "requires": {
- "@types/caseless": "*",
- "@types/node": "*",
- "@types/tough-cookie": "*",
- "form-data": "^2.5.0"
- },
- "dependencies": {
- "form-data": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz",
- "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==",
- "requires": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.6",
- "mime-types": "^2.1.12"
- }
- }
- }
- },
"@types/stack-utils": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz",
"integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==",
"dev": true
},
- "@types/tough-cookie": {
- "version": "2.3.6",
- "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.6.tgz",
- "integrity": "sha512-wHNBMnkoEBiRAd3s8KTKwIuO9biFtTf0LehITzBhSco+HQI0xkXZbLOD55SW3Aqw3oUkHstkm5SPv58yaAdFPQ=="
- },
"@types/yargs": {
"version": "15.0.3",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.3.tgz",
@@ -1208,6 +1170,14 @@
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
},
+ "axios": {
+ "version": "0.19.2",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
+ "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
+ "requires": {
+ "follow-redirects": "1.5.10"
+ }
+ },
"babel-jest": {
"version": "25.1.0",
"resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.1.0.tgz",
@@ -2682,6 +2652,29 @@
"integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==",
"dev": true
},
+ "follow-redirects": {
+ "version": "1.5.10",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
+ "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
+ "requires": {
+ "debug": "=3.1.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
"for-in": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
@@ -5832,9 +5825,9 @@
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
},
"qs": {
- "version": "6.5.2",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
- "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
+ "version": "6.9.1",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.1.tgz",
+ "integrity": "sha512-Cxm7/SS/y/Z3MHWSxXb8lIFqgqBowP5JMlTUFyJN88y0SGQhVmZnqFK/PeuMX9LzUyWsqqhNxIyg0jlzq946yA=="
},
"react-is": {
"version": "16.12.0",
@@ -5931,6 +5924,13 @@
"tough-cookie": "~2.4.3",
"tunnel-agent": "^0.6.0",
"uuid": "^3.3.2"
+ },
+ "dependencies": {
+ "qs": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
+ }
}
},
"request-promise-core": {
diff --git a/package.json b/package.json
index 7cf621d..2ec5360 100644
--- a/package.json
+++ b/package.json
@@ -17,11 +17,11 @@
"database"
],
"dependencies": {
- "@types/request": "^2.48.4",
+ "axios": "^0.19.2",
"cloudant-follow": "^0.18.2",
"debug": "^4.1.1",
"errs": "^0.3.2",
- "request": "^2.88.0"
+ "qs": "^6.9.1"
},
"devDependencies": {
"async": "^2.6.2",
@@ -32,7 +32,7 @@
"scripts": {
"standard": "standard --fix",
"test": "standard && npm run jest",
- "jest": "jest test/* --coverage"
+ "jest": "jest test/* --coverage --env=node"
},
"main": "./lib/nano.js",
"types": "./lib/nano.d.ts",