gaxios
Advanced tools
Comparing version 1.8.4 to 2.0.0
@@ -10,5 +10,5 @@ /// <reference types="node" /> | ||
} | ||
export declare type Headers = { | ||
export interface Headers { | ||
[index: string]: any; | ||
}; | ||
} | ||
export declare type GaxiosPromise<T = any> = Promise<GaxiosResponse<T>>; | ||
@@ -15,0 +15,0 @@ export interface GaxiosResponse<T = any> { |
@@ -15,2 +15,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
// tslint:disable no-any | ||
class GaxiosError extends Error { | ||
@@ -17,0 +18,0 @@ constructor(message, options, response) { |
@@ -14,22 +14,18 @@ "use strict"; | ||
// limitations under the License. | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const extend = require("extend"); | ||
const node_fetch_1 = require("node-fetch"); | ||
const qs = require("querystring"); | ||
const stream = require("stream"); | ||
const url = require("url"); | ||
const extend_1 = __importDefault(require("extend")); | ||
const node_fetch_1 = __importDefault(require("node-fetch")); | ||
const querystring_1 = __importDefault(require("querystring")); | ||
const stream_1 = __importDefault(require("stream")); | ||
const url_1 = __importDefault(require("url")); | ||
const common_1 = require("./common"); | ||
const isbrowser_1 = require("./isbrowser"); | ||
const retry_1 = require("./retry"); | ||
const URL = isbrowser_1.isBrowser() ? window.URL : url.URL; | ||
// tslint:disable no-any | ||
const URL = isbrowser_1.isBrowser() ? window.URL : url_1.default.URL; | ||
const fetch = isbrowser_1.isBrowser() ? window.fetch : node_fetch_1.default; | ||
// tslint:disable-next-line variable-name no-any | ||
// tslint:disable-next-line variable-name | ||
let HttpsProxyAgent; | ||
@@ -39,4 +35,6 @@ // Figure out if we should be using a proxy. Only if it's required, load | ||
function loadProxy() { | ||
const proxy = process.env.HTTPS_PROXY || process.env.https_proxy || | ||
process.env.HTTP_PROXY || process.env.http_proxy; | ||
const proxy = process.env.HTTPS_PROXY || | ||
process.env.https_proxy || | ||
process.env.HTTP_PROXY || | ||
process.env.http_proxy; | ||
if (proxy) { | ||
@@ -61,55 +59,49 @@ HttpsProxyAgent = require('https-proxy-agent'); | ||
*/ | ||
request(opts = {}) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
opts = this.validateOpts(opts); | ||
try { | ||
let translatedResponse; | ||
if (opts.adapter) { | ||
translatedResponse = yield opts.adapter(opts); | ||
} | ||
else { | ||
const res = yield fetch(opts.url, opts); | ||
const data = yield this.getResponseData(opts, res); | ||
translatedResponse = this.translateResponse(opts, res, data); | ||
} | ||
if (!opts.validateStatus(translatedResponse.status)) { | ||
throw new common_1.GaxiosError(`Request failed with status code ${translatedResponse.status}`, opts, translatedResponse); | ||
} | ||
return translatedResponse; | ||
async request(opts = {}) { | ||
opts = this.validateOpts(opts); | ||
try { | ||
let translatedResponse; | ||
if (opts.adapter) { | ||
translatedResponse = await opts.adapter(opts); | ||
} | ||
catch (e) { | ||
const err = e; | ||
err.config = opts; | ||
const { shouldRetry, config } = yield retry_1.getRetryConfig(e); | ||
if (shouldRetry && config) { | ||
err.config.retryConfig.currentRetryAttempt = | ||
config.retryConfig.currentRetryAttempt; | ||
return this.request(err.config); | ||
} | ||
throw err; | ||
else { | ||
const res = await fetch(opts.url, opts); | ||
const data = await this.getResponseData(opts, res); | ||
translatedResponse = this.translateResponse(opts, res, data); | ||
} | ||
}); | ||
} | ||
getResponseData(opts, res) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
switch (opts.responseType) { | ||
case 'stream': | ||
return res.body; | ||
case 'json': | ||
let data = yield res.text(); | ||
try { | ||
data = JSON.parse(data); | ||
} | ||
catch (e) { | ||
} | ||
return data; | ||
case 'arraybuffer': | ||
return res.arrayBuffer(); | ||
case 'blob': | ||
return res.blob(); | ||
default: | ||
return res.text(); | ||
if (!opts.validateStatus(translatedResponse.status)) { | ||
throw new common_1.GaxiosError(`Request failed with status code ${translatedResponse.status}`, opts, translatedResponse); | ||
} | ||
}); | ||
return translatedResponse; | ||
} | ||
catch (e) { | ||
const err = e; | ||
err.config = opts; | ||
const { shouldRetry, config } = await retry_1.getRetryConfig(e); | ||
if (shouldRetry && config) { | ||
err.config.retryConfig.currentRetryAttempt = config.retryConfig.currentRetryAttempt; | ||
return this.request(err.config); | ||
} | ||
throw err; | ||
} | ||
} | ||
async getResponseData(opts, res) { | ||
switch (opts.responseType) { | ||
case 'stream': | ||
return res.body; | ||
case 'json': | ||
let data = await res.text(); | ||
try { | ||
data = JSON.parse(data); | ||
} | ||
catch (e) { } | ||
return data; | ||
case 'arraybuffer': | ||
return res.arrayBuffer(); | ||
case 'blob': | ||
return res.blob(); | ||
default: | ||
return res.text(); | ||
} | ||
} | ||
/** | ||
@@ -120,3 +112,3 @@ * Validates the options, and merges them with defaults. | ||
validateOpts(options) { | ||
const opts = extend(true, {}, this.defaults, options); | ||
const opts = extend_1.default(true, {}, this.defaults, options); | ||
if (!opts.url) { | ||
@@ -132,3 +124,3 @@ throw new Error('URL is required.'); | ||
opts.url = `${parsedUrl.origin}${parsedUrl.pathname}`; | ||
opts.params = extend(qs.parse(parsedUrl.search.substr(1)), // removes leading ? | ||
opts.params = extend_1.default(querystring_1.default.parse(parsedUrl.search.substr(1)), // removes leading ? | ||
opts.params); | ||
@@ -189,6 +181,6 @@ opts.paramsSerializer = opts.paramsSerializer || this.paramsSerializer; | ||
paramsSerializer(params) { | ||
return qs.stringify(params); | ||
return querystring_1.default.stringify(params); | ||
} | ||
isReadableStream(obj) { | ||
return obj instanceof stream.Readable && typeof obj._read === 'function'; | ||
return obj instanceof stream_1.default.Readable && typeof obj._read === 'function'; | ||
} | ||
@@ -206,3 +198,3 @@ translateResponse(opts, res, data) { | ||
status: res.status, | ||
statusText: res.statusText | ||
statusText: res.statusText, | ||
}; | ||
@@ -209,0 +201,0 @@ } |
import { GaxiosOptions } from './common'; | ||
import { Gaxios } from './gaxios'; | ||
export { GaxiosError, GaxiosPromise, GaxiosResponse, Headers, RetryConfig } from './common'; | ||
export { GaxiosError, GaxiosPromise, GaxiosResponse, Headers, RetryConfig, } from './common'; | ||
export { Gaxios, GaxiosOptions }; | ||
@@ -5,0 +5,0 @@ /** |
@@ -14,10 +14,2 @@ "use strict"; | ||
// limitations under the License. | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -37,8 +29,6 @@ const gaxios_1 = require("./gaxios"); | ||
*/ | ||
function request(opts) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return exports.instance.request(opts); | ||
}); | ||
async function request(opts) { | ||
return exports.instance.request(opts); | ||
} | ||
exports.request = request; | ||
//# sourceMappingURL=index.js.map |
@@ -19,5 +19,5 @@ "use strict"; | ||
function isBrowser() { | ||
return typeof (window) !== 'undefined'; | ||
return typeof window !== 'undefined'; | ||
} | ||
exports.isBrowser = isBrowser; | ||
//# sourceMappingURL=isbrowser.js.map |
@@ -14,65 +14,62 @@ "use strict"; | ||
// limitations under the License. | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
function getRetryConfig(err) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let config = getConfig(err); | ||
if ((!err || !err.config) || (!config && !err.config.retry)) { | ||
return { shouldRetry: false }; | ||
} | ||
config = config || {}; | ||
config.currentRetryAttempt = config.currentRetryAttempt || 0; | ||
config.retry = | ||
(config.retry === undefined || config.retry === null) ? 3 : config.retry; | ||
config.retryDelay = config.retryDelay || 100; | ||
config.httpMethodsToRetry = | ||
config.httpMethodsToRetry || ['GET', 'HEAD', 'PUT', 'OPTIONS', 'DELETE']; | ||
config.noResponseRetries = (config.noResponseRetries === undefined || | ||
config.noResponseRetries === null) ? | ||
2 : | ||
config.noResponseRetries; | ||
// If this wasn't in the list of status codes where we want | ||
// to automatically retry, return. | ||
const retryRanges = [ | ||
// https://en.wikipedia.org/wiki/List_of_HTTP_status_codes | ||
// 1xx - Retry (Informational, request still processing) | ||
// 2xx - Do not retry (Success) | ||
// 3xx - Do not retry (Redirect) | ||
// 4xx - Do not retry (Client errors) | ||
// 429 - Retry ("Too Many Requests") | ||
// 5xx - Retry (Server errors) | ||
[100, 199], [429, 429], [500, 599] | ||
]; | ||
config.statusCodesToRetry = config.statusCodesToRetry || retryRanges; | ||
// Put the config back into the err | ||
err.config.retryConfig = config; | ||
// Determine if we should retry the request | ||
const shouldRetryFn = config.shouldRetry || shouldRetryRequest; | ||
if (!shouldRetryFn(err)) { | ||
return { shouldRetry: false, config: err.config }; | ||
} | ||
// Calculate time to wait with exponential backoff. | ||
// Formula: (2^c - 1 / 2) * 1000 | ||
const delay = (Math.pow(2, config.currentRetryAttempt) - 1) / 2 * 1000; | ||
// We're going to retry! Incremenent the counter. | ||
err.config.retryConfig.currentRetryAttempt += 1; | ||
// Create a promise that invokes the retry after the backOffDelay | ||
const backoff = new Promise(resolve => { | ||
setTimeout(resolve, delay); | ||
}); | ||
// Notify the user if they added an `onRetryAttempt` handler | ||
if (config.onRetryAttempt) { | ||
config.onRetryAttempt(err); | ||
} | ||
// Return the promise in which recalls Gaxios to retry the request | ||
yield backoff; | ||
return { shouldRetry: true, config: err.config }; | ||
async function getRetryConfig(err) { | ||
let config = getConfig(err); | ||
if (!err || !err.config || (!config && !err.config.retry)) { | ||
return { shouldRetry: false }; | ||
} | ||
config = config || {}; | ||
config.currentRetryAttempt = config.currentRetryAttempt || 0; | ||
config.retry = | ||
config.retry === undefined || config.retry === null ? 3 : config.retry; | ||
config.retryDelay = config.retryDelay || 100; | ||
config.httpMethodsToRetry = config.httpMethodsToRetry || [ | ||
'GET', | ||
'HEAD', | ||
'PUT', | ||
'OPTIONS', | ||
'DELETE', | ||
]; | ||
config.noResponseRetries = | ||
config.noResponseRetries === undefined || config.noResponseRetries === null | ||
? 2 | ||
: config.noResponseRetries; | ||
// If this wasn't in the list of status codes where we want | ||
// to automatically retry, return. | ||
const retryRanges = [ | ||
// https://en.wikipedia.org/wiki/List_of_HTTP_status_codes | ||
// 1xx - Retry (Informational, request still processing) | ||
// 2xx - Do not retry (Success) | ||
// 3xx - Do not retry (Redirect) | ||
// 4xx - Do not retry (Client errors) | ||
// 429 - Retry ("Too Many Requests") | ||
// 5xx - Retry (Server errors) | ||
[100, 199], | ||
[429, 429], | ||
[500, 599], | ||
]; | ||
config.statusCodesToRetry = config.statusCodesToRetry || retryRanges; | ||
// Put the config back into the err | ||
err.config.retryConfig = config; | ||
// Determine if we should retry the request | ||
const shouldRetryFn = config.shouldRetry || shouldRetryRequest; | ||
if (!shouldRetryFn(err)) { | ||
return { shouldRetry: false, config: err.config }; | ||
} | ||
// Calculate time to wait with exponential backoff. | ||
// Formula: (2^c - 1 / 2) * 1000 | ||
const delay = ((Math.pow(2, config.currentRetryAttempt) - 1) / 2) * 1000; | ||
// We're going to retry! Incremenent the counter. | ||
err.config.retryConfig.currentRetryAttempt += 1; | ||
// Create a promise that invokes the retry after the backOffDelay | ||
const backoff = new Promise(resolve => { | ||
setTimeout(resolve, delay); | ||
}); | ||
// Notify the user if they added an `onRetryAttempt` handler | ||
if (config.onRetryAttempt) { | ||
config.onRetryAttempt(err); | ||
} | ||
// Return the promise in which recalls Gaxios to retry the request | ||
await backoff; | ||
return { shouldRetry: true, config: err.config }; | ||
} | ||
@@ -92,3 +89,3 @@ exports.getRetryConfig = getRetryConfig; | ||
if (!err.response && | ||
((config.currentRetryAttempt || 0) >= config.noResponseRetries)) { | ||
(config.currentRetryAttempt || 0) >= config.noResponseRetries) { | ||
return false; | ||
@@ -95,0 +92,0 @@ } |
{ | ||
"name": "gaxios", | ||
"version": "1.8.4", | ||
"version": "2.0.0", | ||
"description": "A simple common HTTP client specifically for Google APIs and services.", | ||
@@ -29,2 +29,5 @@ "main": "build/src/index.js", | ||
], | ||
"engines": { | ||
"node": ">=8" | ||
}, | ||
"author": "Google, LLC", | ||
@@ -48,3 +51,3 @@ "license": "Apache-2.0", | ||
"execa": "^1.0.0", | ||
"gts": "^0.9.0", | ||
"gts": "^1.0.0", | ||
"is-docker": "^2.0.0", | ||
@@ -63,3 +66,3 @@ "karma": "^4.0.0", | ||
"nock": "^10.0.6", | ||
"null-loader": "^0.1.1", | ||
"null-loader": "^1.0.0", | ||
"nyc": "^14.0.0", | ||
@@ -66,0 +69,0 @@ "puppeteer": "^1.12.2", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
48723
571