ibm-cloud-sdk-core
Advanced tools
Comparing version 0.2.7 to 0.2.8
@@ -0,1 +1,8 @@ | ||
## [0.2.8](https://github.com/IBM/node-sdk-core/compare/v0.2.7...v0.2.8) (2019-05-30) | ||
### Bug Fixes | ||
* default request body size to Infinity ([6cea2b9](https://github.com/IBM/node-sdk-core/commit/6cea2b9)) | ||
## [0.2.7](https://github.com/IBM/node-sdk-core/compare/v0.2.6...v0.2.7) (2019-05-24) | ||
@@ -2,0 +9,0 @@ |
@@ -39,2 +39,3 @@ /** | ||
private iamClientSecret; | ||
private requestWrapperInstance; | ||
/** | ||
@@ -41,0 +42,0 @@ * IAM Token Manager Service |
@@ -65,2 +65,3 @@ "use strict"; | ||
} | ||
this.requestWrapperInstance = new requestwrapper_1.RequestWrapper(); | ||
} | ||
@@ -158,3 +159,3 @@ /** | ||
}; | ||
requestwrapper_1.sendRequest(parameters, cb); | ||
this.requestWrapperInstance.sendRequest(parameters, cb); | ||
}; | ||
@@ -182,3 +183,3 @@ /** | ||
}; | ||
requestwrapper_1.sendRequest(parameters, cb); | ||
this.requestWrapperInstance.sendRequest(parameters, cb); | ||
}; | ||
@@ -185,0 +186,0 @@ /** |
@@ -57,2 +57,3 @@ /** | ||
protected tokenManager: any; | ||
private requestWrapperInstance; | ||
/** | ||
@@ -59,0 +60,0 @@ * Internal base class that other services inherit from |
@@ -124,2 +124,3 @@ "use strict"; | ||
this._options.rejectUnauthorized = !options.disable_ssl_verification; | ||
this.requestWrapperInstance = new requestwrapper_1.RequestWrapper(this._options); | ||
} | ||
@@ -209,2 +210,3 @@ /** | ||
BaseService.prototype.createRequest = function (parameters, callback) { | ||
var _this = this; | ||
if (Boolean(this.tokenManager)) { | ||
@@ -217,7 +219,7 @@ return this.tokenManager.getToken(function (err, accessToken) { | ||
"Bearer " + accessToken; | ||
return requestwrapper_1.sendRequest(parameters, callback); | ||
return _this.requestWrapperInstance.sendRequest(parameters, callback); | ||
}); | ||
} | ||
else { | ||
return requestwrapper_1.sendRequest(parameters, callback); | ||
return this.requestWrapperInstance.sendRequest(parameters, callback); | ||
} | ||
@@ -224,0 +226,0 @@ }; |
@@ -16,19 +16,23 @@ /** | ||
*/ | ||
/** | ||
* Format error returned by axios | ||
* @param {Function} cb the request callback | ||
* @private | ||
* @returns {request.RequestCallback} | ||
*/ | ||
export declare function formatError(axiosError: any): any; | ||
/** | ||
* Creates the request. | ||
* 1. Merge default options with user provided options | ||
* 2. Checks for missing parameters | ||
* 3. Encode path and query parameters | ||
* 4. Call the api | ||
* @private | ||
* @returns {ReadableStream|undefined} | ||
* @throws {Error} | ||
*/ | ||
export declare function sendRequest(parameters: any, _callback: any): void; | ||
export declare class RequestWrapper { | ||
private axiosInstance; | ||
constructor(axiosOptions?: any); | ||
/** | ||
* Creates the request. | ||
* 1. Merge default options with user provided options | ||
* 2. Checks for missing parameters | ||
* 3. Encode path and query parameters | ||
* 4. Call the api | ||
* @private | ||
* @returns {ReadableStream|undefined} | ||
* @throws {Error} | ||
*/ | ||
sendRequest(parameters: any, _callback: any): void; | ||
/** | ||
* Format error returned by axios | ||
* @param {Function} cb the request callback | ||
* @private | ||
* @returns {request.RequestCallback} | ||
*/ | ||
formatError(axiosError: any): any; | ||
} |
@@ -28,12 +28,241 @@ "use strict"; | ||
var globalTransactionId = 'x-global-transaction-id'; | ||
// axios sets the default Content-Type for `post`, `put`, and `patch` operations | ||
// to 'application/x-www-form-urlencoded'. This causes problems, so overriding the | ||
// defaults here | ||
['post', 'put', 'patch'].forEach(function (method) { | ||
axios_1.default.defaults.headers[method]['Content-Type'] = 'application/json'; | ||
}); | ||
// allow user to debug axios | ||
if (process.env.NODE_DEBUG === 'axios') { | ||
require('axios-debug')(axios_1.default); // tslint:disable-line:no-var-requires | ||
} | ||
// Limit the type of axios configs to be customizable | ||
var allowedAxiosConfig = ['transformRequest', 'transformResponse', 'paramsSerializer', 'paramsSerializer', 'timeout', 'withCredentials', 'adapter', 'responseType', 'responseEncoding', 'xsrfCookieName', 'xsrfHeaderName', 'onUploadProgress', 'onDownloadProgress', 'maxContentLength', 'validateStatus', 'maxRedirects', 'socketPath', 'httpAgent', 'httpsAgent', 'proxy', 'cancelToken']; | ||
var RequestWrapper = /** @class */ (function () { | ||
function RequestWrapper(axiosOptions) { | ||
axiosOptions = axiosOptions || {}; | ||
// override several axios defaults | ||
// axios sets the default Content-Type for `post`, `put`, and `patch` operations | ||
// to 'application/x-www-form-urlencoded'. This causes problems, so overriding the | ||
// defaults here | ||
var axiosConfig = { | ||
httpsAgent: new https.Agent({ | ||
rejectUnauthorized: axiosOptions.rejectUnauthorized | ||
}), | ||
maxContentLength: Infinity, | ||
headers: { | ||
post: { | ||
'Content-Type': 'application/json' | ||
}, | ||
put: { | ||
'Content-Type': 'application/json' | ||
}, | ||
patch: { | ||
'Content-Type': 'application/json' | ||
}, | ||
} | ||
}; | ||
// merge valid Axios Config into default. | ||
extend(true, axiosConfig, allowedAxiosConfig.reduce(function (reducedConfig, key) { | ||
reducedConfig[key] = axiosOptions[key]; | ||
return reducedConfig; | ||
}, {})); | ||
this.axiosInstance = axios_1.default.create(axiosConfig); | ||
// set debug interceptors | ||
if (process.env.NODE_DEBUG === 'axios') { | ||
this.axiosInstance.interceptors.request.use(function (config) { | ||
console.debug('Request:'); | ||
try { | ||
console.debug(JSON.stringify(config, null, 2)); | ||
} | ||
catch (_a) { | ||
console.debug(config); | ||
} | ||
return config; | ||
}, function (error) { | ||
console.debug('Error:'); | ||
try { | ||
console.debug(JSON.stringify(error, null, 2)); | ||
} | ||
catch (_a) { | ||
console.debug(error); | ||
} | ||
return Promise.reject(error); | ||
}); | ||
this.axiosInstance.interceptors.response.use(function (response) { | ||
console.debug('Response:'); | ||
try { | ||
console.debug(JSON.stringify(response, null, 2)); | ||
} | ||
catch (_a) { | ||
console.debug(response); | ||
} | ||
return response; | ||
}, function (error) { | ||
console.debug('Error:'); | ||
try { | ||
console.debug(JSON.stringify(error, null, 2)); | ||
} | ||
catch (_a) { | ||
console.debug(error); | ||
} | ||
return Promise.reject(error); | ||
}); | ||
} | ||
} | ||
/** | ||
* Creates the request. | ||
* 1. Merge default options with user provided options | ||
* 2. Checks for missing parameters | ||
* 3. Encode path and query parameters | ||
* 4. Call the api | ||
* @private | ||
* @returns {ReadableStream|undefined} | ||
* @throws {Error} | ||
*/ | ||
RequestWrapper.prototype.sendRequest = function (parameters, _callback) { | ||
var _this = this; | ||
var options = extend(true, {}, parameters.defaultOptions, parameters.options); | ||
var path = options.path, body = options.body, form = options.form, formData = options.formData, qs = options.qs, method = options.method; | ||
var url = options.url, headers = options.headers; | ||
var multipartForm = new FormData(); | ||
// Form params | ||
if (formData) { | ||
// Remove keys with undefined/null values | ||
// Remove empty objects | ||
// Remove non-valid inputs for buildRequestFileObject, | ||
// i.e things like {contentType: <contentType>} | ||
Object.keys(formData).forEach(function (key) { | ||
if (formData[key] == null || | ||
helper_1.isEmptyObject(formData[key]) || | ||
(formData[key].hasOwnProperty('contentType') && !formData[key].hasOwnProperty('data'))) { | ||
delete formData[key]; | ||
} | ||
}); | ||
// Convert file form parameters to request-style objects | ||
Object.keys(formData).forEach(function (key) { | ||
if (formData[key].data != null) { | ||
formData[key] = helper_1.buildRequestFileObject(formData[key]); | ||
} | ||
}); | ||
// Stringify arrays | ||
Object.keys(formData).forEach(function (key) { | ||
if (Array.isArray(formData[key])) { | ||
formData[key] = formData[key].join(','); | ||
} | ||
}); | ||
// Convert non-file form parameters to strings | ||
Object.keys(formData).forEach(function (key) { | ||
if (!helper_1.isFileParam(formData[key]) && | ||
!Array.isArray(formData[key]) && | ||
typeof formData[key] === 'object') { | ||
(formData[key] = JSON.stringify(formData[key])); | ||
} | ||
}); | ||
// build multipart form data | ||
Object.keys(formData).forEach(function (key) { | ||
// handle files differently to maintain options | ||
if (formData[key].value) { | ||
multipartForm.append(key, formData[key].value, formData[key].options); | ||
} | ||
else { | ||
multipartForm.append(key, formData[key]); | ||
} | ||
}); | ||
} | ||
// Path params | ||
url = parsePath(url, path); | ||
// Headers | ||
options.headers = extend({}, options.headers); | ||
// Convert array-valued query params to strings | ||
if (qs && Object.keys(qs).length > 0) { | ||
Object.keys(qs).forEach(function (key) { return Array.isArray(qs[key]) && (qs[key] = qs[key].join(',')); }); | ||
} | ||
// Add service default endpoint if options.url start with / | ||
if (url && url.charAt(0) === '/') { | ||
url = parameters.defaultOptions.url + url; | ||
} | ||
var data = body; | ||
if (form) { | ||
data = querystring.stringify(form); | ||
headers['Content-type'] = 'application/x-www-form-urlencoded'; | ||
} | ||
if (formData) { | ||
data = multipartForm; | ||
// form-data generates headers that MUST be included or the request will fail | ||
headers = extend(true, {}, headers, multipartForm.getHeaders()); | ||
} | ||
// TEMPORARY: Disabling gzipping due to bug in axios until fix is released: | ||
// https://github.com/axios/axios/pull/1129 | ||
// accept gzip encoded responses if Accept-Encoding is not already set | ||
// headers['Accept-Encoding'] = headers['Accept-Encoding'] || 'gzip'; | ||
var requestParams = { | ||
url: url, | ||
method: method, | ||
headers: headers, | ||
params: qs, | ||
data: data, | ||
responseType: options.responseType || 'json', | ||
paramsSerializer: function (params) { | ||
return querystring.stringify(params); | ||
}, | ||
}; | ||
this.axiosInstance(requestParams) | ||
.then(function (res) { | ||
delete res.config; | ||
delete res.request; | ||
// the other sdks use the interface `result` for the body | ||
_callback(null, res.data, res); | ||
}) | ||
.catch(function (error) { | ||
_callback(_this.formatError(error)); | ||
}); | ||
}; | ||
/** | ||
* Format error returned by axios | ||
* @param {Function} cb the request callback | ||
* @private | ||
* @returns {request.RequestCallback} | ||
*/ | ||
RequestWrapper.prototype.formatError = function (axiosError) { | ||
// return an actual error object, | ||
// but make it flexible so we can add properties like 'body' | ||
var error = new Error(); | ||
// axios specific handling | ||
// this branch is for an error received from the service | ||
if (axiosError.response) { | ||
axiosError = axiosError.response; | ||
// The request was made and the server responded with a status code | ||
// that falls out of the range of 2xx | ||
delete axiosError.config; | ||
delete axiosError.request; | ||
error.name = axiosError.statusText; | ||
error.code = axiosError.status; | ||
error.message = parseServiceErrorMessage(axiosError.data) || axiosError.statusText; | ||
// some services bury the useful error message within 'data' | ||
// adding it to the error under the key 'body' as a string or object | ||
var errorBody = void 0; | ||
try { | ||
// try/catch to handle objects with circular references | ||
errorBody = JSON.stringify(axiosError.data); | ||
} | ||
catch (e) { | ||
// ignore the error, use the object, and tack on a warning | ||
errorBody = axiosError.data; | ||
errorBody.warning = 'body contains circular reference'; | ||
} | ||
error.body = errorBody; | ||
// attach headers to error object | ||
error.headers = axiosError.headers; | ||
// print a more descriptive error message for auth issues | ||
if (isAuthenticationError(axiosError)) { | ||
error.message = 'Access is denied due to invalid credentials.'; | ||
} | ||
} | ||
else if (axiosError.request) { | ||
// The request was made but no response was received | ||
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of | ||
// http.ClientRequest in node.js | ||
error.message = 'Response not received. Body of error is HTTP ClientRequest object'; | ||
error.body = axiosError.request; | ||
} | ||
else { | ||
// Something happened in setting up the request that triggered an Error | ||
error.message = axiosError.message; | ||
} | ||
return error; | ||
}; | ||
return RequestWrapper; | ||
}()); | ||
exports.RequestWrapper = RequestWrapper; | ||
/** | ||
@@ -107,167 +336,2 @@ * @private | ||
} | ||
/** | ||
* Format error returned by axios | ||
* @param {Function} cb the request callback | ||
* @private | ||
* @returns {request.RequestCallback} | ||
*/ | ||
function formatError(axiosError) { | ||
// return an actual error object, | ||
// but make it flexible so we can add properties like 'body' | ||
var error = new Error(); | ||
// axios specific handling | ||
// this branch is for an error received from the service | ||
if (axiosError.response) { | ||
axiosError = axiosError.response; | ||
// The request was made and the server responded with a status code | ||
// that falls out of the range of 2xx | ||
delete axiosError.config; | ||
delete axiosError.request; | ||
error.name = axiosError.statusText; | ||
error.code = axiosError.status; | ||
error.message = parseServiceErrorMessage(axiosError.data) || axiosError.statusText; | ||
// some services bury the useful error message within 'data' | ||
// adding it to the error under the key 'body' as a string or object | ||
var errorBody = void 0; | ||
try { | ||
// try/catch to handle objects with circular references | ||
errorBody = JSON.stringify(axiosError.data); | ||
} | ||
catch (e) { | ||
// ignore the error, use the object, and tack on a warning | ||
errorBody = axiosError.data; | ||
errorBody.warning = 'body contains circular reference'; | ||
} | ||
error.body = errorBody; | ||
// attach headers to error object | ||
error.headers = axiosError.headers; | ||
// print a more descriptive error message for auth issues | ||
if (isAuthenticationError(axiosError)) { | ||
error.message = 'Access is denied due to invalid credentials.'; | ||
} | ||
} | ||
else if (axiosError.request) { | ||
// The request was made but no response was received | ||
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of | ||
// http.ClientRequest in node.js | ||
error.message = 'Response not received. Body of error is HTTP ClientRequest object'; | ||
error.body = axiosError.request; | ||
} | ||
else { | ||
// Something happened in setting up the request that triggered an Error | ||
error.message = axiosError.message; | ||
} | ||
return error; | ||
} | ||
exports.formatError = formatError; | ||
/** | ||
* Creates the request. | ||
* 1. Merge default options with user provided options | ||
* 2. Checks for missing parameters | ||
* 3. Encode path and query parameters | ||
* 4. Call the api | ||
* @private | ||
* @returns {ReadableStream|undefined} | ||
* @throws {Error} | ||
*/ | ||
function sendRequest(parameters, _callback) { | ||
var options = extend(true, {}, parameters.defaultOptions, parameters.options); | ||
var path = options.path, body = options.body, form = options.form, formData = options.formData, qs = options.qs, method = options.method, rejectUnauthorized = options.rejectUnauthorized; | ||
var url = options.url, headers = options.headers; | ||
var multipartForm = new FormData(); | ||
// Form params | ||
if (formData) { | ||
// Remove keys with undefined/null values | ||
// Remove empty objects | ||
// Remove non-valid inputs for buildRequestFileObject, | ||
// i.e things like {contentType: <contentType>} | ||
Object.keys(formData).forEach(function (key) { | ||
if (formData[key] == null || | ||
helper_1.isEmptyObject(formData[key]) || | ||
(formData[key].hasOwnProperty('contentType') && !formData[key].hasOwnProperty('data'))) { | ||
delete formData[key]; | ||
} | ||
}); | ||
// Convert file form parameters to request-style objects | ||
Object.keys(formData).forEach(function (key) { | ||
if (formData[key].data != null) { | ||
formData[key] = helper_1.buildRequestFileObject(formData[key]); | ||
} | ||
}); | ||
// Stringify arrays | ||
Object.keys(formData).forEach(function (key) { | ||
if (Array.isArray(formData[key])) { | ||
formData[key] = formData[key].join(','); | ||
} | ||
}); | ||
// Convert non-file form parameters to strings | ||
Object.keys(formData).forEach(function (key) { | ||
if (!helper_1.isFileParam(formData[key]) && | ||
!Array.isArray(formData[key]) && | ||
typeof formData[key] === 'object') { | ||
(formData[key] = JSON.stringify(formData[key])); | ||
} | ||
}); | ||
// build multipart form data | ||
Object.keys(formData).forEach(function (key) { | ||
// handle files differently to maintain options | ||
if (formData[key].value) { | ||
multipartForm.append(key, formData[key].value, formData[key].options); | ||
} | ||
else { | ||
multipartForm.append(key, formData[key]); | ||
} | ||
}); | ||
} | ||
// Path params | ||
url = parsePath(url, path); | ||
// Headers | ||
options.headers = extend({}, options.headers); | ||
// Convert array-valued query params to strings | ||
if (qs && Object.keys(qs).length > 0) { | ||
Object.keys(qs).forEach(function (key) { return Array.isArray(qs[key]) && (qs[key] = qs[key].join(',')); }); | ||
} | ||
// Add service default endpoint if options.url start with / | ||
if (url && url.charAt(0) === '/') { | ||
url = parameters.defaultOptions.url + url; | ||
} | ||
var data = body; | ||
if (form) { | ||
data = querystring.stringify(form); | ||
headers['Content-type'] = 'application/x-www-form-urlencoded'; | ||
} | ||
if (formData) { | ||
data = multipartForm; | ||
// form-data generates headers that MUST be included or the request will fail | ||
headers = extend(true, {}, headers, multipartForm.getHeaders()); | ||
} | ||
// TEMPORARY: Disabling gzipping due to bug in axios until fix is released: | ||
// https://github.com/axios/axios/pull/1129 | ||
// accept gzip encoded responses if Accept-Encoding is not already set | ||
// headers['Accept-Encoding'] = headers['Accept-Encoding'] || 'gzip'; | ||
var requestParams = { | ||
url: url, | ||
method: method, | ||
headers: headers, | ||
params: qs, | ||
data: data, | ||
responseType: options.responseType || 'json', | ||
paramsSerializer: function (params) { | ||
return querystring.stringify(params); | ||
}, | ||
// a custom httpsAgent is needed to support ICP | ||
httpsAgent: new https.Agent({ rejectUnauthorized: rejectUnauthorized }), | ||
}; | ||
axios_1.default(extend(true, {}, options, requestParams)) | ||
.then(function (res) { | ||
delete res.config; | ||
delete res.request; | ||
// the other sdks use the interface `result` for the body | ||
_callback(null, res.data, res); | ||
}) | ||
.catch(function (error) { | ||
_callback(formatError(error)); | ||
}); | ||
} | ||
exports.sendRequest = sendRequest; | ||
//# sourceMappingURL=requestwrapper.js.map |
{ | ||
"name": "ibm-cloud-sdk-core", | ||
"version": "0.2.7", | ||
"version": "0.2.8", | ||
"description": "Core functionality to support SDKs generated with IBM's OpenAPI 3 SDK Generator.", | ||
@@ -59,3 +59,2 @@ "main": "./index", | ||
"axios": "^0.18.0", | ||
"axios-debug": "0.0.4", | ||
"dotenv": "^6.2.0", | ||
@@ -62,0 +61,0 @@ "extend": "~3.0.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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
123705
14
1852
3
2
- Removedaxios-debug@0.0.4
- Removedansi-regex@2.1.1(transitive)
- Removedansi-styles@2.2.1(transitive)
- Removedaxios-debug@0.0.4(transitive)
- Removedchalk@1.1.3(transitive)
- Removedescape-string-regexp@1.0.5(transitive)
- Removedhas-ansi@2.0.0(transitive)
- Removedstrip-ansi@3.0.1(transitive)
- Removedsupports-color@2.0.0(transitive)