Socket
Socket
Sign inDemoInstall

ibm-cloud-sdk-core

Package Overview
Dependencies
Maintainers
1
Versions
143
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ibm-cloud-sdk-core - npm Package Compare versions

Comparing version 0.0.1 to 0.0.2

7

lib/base_service.d.ts

@@ -1,3 +0,1 @@

/// <reference types="request" />
import request = require('request');
export interface HeaderOptions {

@@ -12,3 +10,2 @@ 'X-Watson-Learning-Opt-Out'?: boolean;

password?: string;
api_key?: string;
apikey?: string;

@@ -26,3 +23,2 @@ use_unauthenticated?: boolean;

url: string;
jar?: request.CookieJar;
qs: any;

@@ -34,3 +30,2 @@ rejectUnauthorized?: boolean;

password?: string;
api_key?: string;
url?: string;

@@ -71,3 +66,3 @@ iam_access_token?: string;

*/
getCredentials(): Credentials;
getServiceCredentials(): Credentials;
/**

@@ -74,0 +69,0 @@ * Set an IAM access token to use when authenticating with the service.

39

lib/base_service.js

@@ -22,3 +22,2 @@ "use strict";

var extend = require("extend");
var request = require("request");
var semver = require("semver");

@@ -33,6 +32,8 @@ var vcapServices = require("vcap_services");

((obj.username && obj.password) ||
obj.api_key ||
obj.iam_access_token ||
obj.iam_apikey));
}
function isForICP(cred) {
return cred && cred.startsWith('icp-');
}
function hasBasicCredentials(obj) {

@@ -42,3 +43,3 @@ return obj && obj.username && obj.password && !usesBasicForIam(obj);

function hasIamCredentials(obj) {
return obj && (obj.iam_apikey || obj.iam_access_token);
return obj && (obj.iam_apikey || obj.iam_access_token) && !isForICP(obj.iam_apikey);
}

@@ -48,3 +49,3 @@ // returns true if the user provides basic auth creds with the intention

function usesBasicForIam(obj) {
return obj.username === 'apikey' && !obj.password.startsWith('icp-');
return obj.username === 'apikey' && !isForICP(obj.password);
}

@@ -102,7 +103,2 @@ // returns true if the string has a curly bracket or quote as the first or last character

var _options = this.initCredentials(options);
// If url is not specified, visual recognition requires gateway-a for CF instances
// https://github.ibm.com/Watson/developer-experience/issues/4589
if (_options && this.name === 'watson_vision_combined' && !_options.url && _options.api_key && !_options.iam_apikey) {
_options.url = 'https://gateway-a.watsonplatform.net/visual-recognition/api';
}
if (options.url) {

@@ -140,3 +136,3 @@ _options.url = helper_1.stripTrailingSlash(options.url);

*/
BaseService.prototype.getCredentials = function () {
BaseService.prototype.getServiceCredentials = function () {
var credentials = {};

@@ -149,5 +145,2 @@ if (this._options.username) {

}
if (this._options.api_key) {
credentials.api_key = this._options.api_key;
}
if (this._options.url) {

@@ -248,6 +241,2 @@ credentials.url = this._options.url;

}
if (options.api_key || options.apikey) {
_options.api_key = options.api_key || options.apikey;
}
_options.jar = request.jar();
// Get credentials from environment properties or Bluemix,

@@ -260,6 +249,14 @@ // but prefer credentials provided programatically

'constructor argument. Refer to the documentation for the ' +
'required parameters. Common examples are username/password, ' +
'api_key, and iam_access_token.';
'required parameters. Common examples are username/password and ' +
'iam_access_token.';
throw new Error(errorMessage);
}
// handle iam_apikey containing an ICP api key
if (isForICP(_options.iam_apikey)) {
_options.username = 'apikey';
_options.password = _options.iam_apikey;
// remove apikey so code doesnt confuse credentials as iam
delete _options.iam_apikey;
delete options.iam_apikey;
}
if (!hasIamCredentials(_options) && !usesBasicForIam(_options)) {

@@ -272,5 +269,2 @@ if (hasBasicCredentials(_options)) {

}
else {
_options.qs = extend({ api_key: _options.api_key }, _options.qs);
}
}

@@ -318,3 +312,2 @@ }

password: password,
api_key: apiKey,
url: url,

@@ -321,0 +314,0 @@ iam_access_token: iamAccessToken,

@@ -58,6 +58,2 @@ "use strict";

}
else if (typeof inputData === 'string') {
// if the inputData is a string
contentType = fileType(Buffer.from(inputData));
}
return contentType ? contentType.mime : null;

@@ -64,0 +60,0 @@ }

@@ -1,5 +0,3 @@

/// <reference types="request" />
import request = require('request');
/**
* Check if the service/request have error and try to format them.
* Format error returned by axios
* @param {Function} cb the request callback

@@ -9,3 +7,3 @@ * @private

*/
export declare function formatErrorIfExists(cb: Function): request.RequestCallback;
export declare function formatError(axiosError: any): any;
/**

@@ -21,2 +19,2 @@ * Creates the request.

*/
export declare function sendRequest(parameters: any, _callback: any): any;
export declare function sendRequest(parameters: any, _callback: any): void;

@@ -18,5 +18,7 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
var axios_1 = require("axios");
var extend = require("extend");
var request = require("request");
var stream_1 = require("stream");
var FormData = require("form-data");
var https = require("https");
var querystring = require("querystring");
var helper_1 = require("./helper");

@@ -43,3 +45,22 @@ // tslint:disable-next-line:no-var-requires

/**
* Check if the service/request have error and try to format them.
* Determine if the error is due to bad credentials
* @private
* @param {Object} error - error object returned from axios
* @returns {boolean} true if error is due to authentication
*/
function isAuthenticationError(error) {
var isAuthErr = false;
var code = error.status;
var body = error.data;
// handle specific error from iam service, should be relevant across platforms
var isIamServiceError = body.context &&
body.context.url &&
body.context.url.indexOf('iam') > -1;
if (code === 401 || code === 403 || isIamServiceError) {
isAuthErr = true;
}
return isAuthErr;
}
/**
* Format error returned by axios
* @param {Function} cb the request callback

@@ -49,85 +70,52 @@ * @private

*/
function formatErrorIfExists(cb) {
return function (error, response, body) {
// eslint-disable-line complexity
// If we have an error return it.
if (error) {
// first ensure that it's an instanceof Error
if (!(error instanceof Error)) {
body = error;
error = new Error(error.message || error.error || error);
error.body = body;
}
if (response && response.headers) {
error[globalTransactionId] = response.headers[globalTransactionId];
}
cb(error, body, response);
return;
}
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
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 = axiosError.data.error && typeof axiosError.data.error === 'string'
? axiosError.data.error
: 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 {
// in most cases, request will have already parsed the body as JSON
body = JSON.parse(body);
// try/catch to handle objects with circular references
errorBody = JSON.stringify(axiosError.data);
}
catch (e) {
// if it fails, just return the body as-is
// ignore the error, use the object, and tack on a warning
errorBody = axiosError.data;
errorBody.warning = 'body contains circular reference';
}
// for api-key services
if (response.statusMessage === 'invalid-api-key') {
var error_1 = {
error: response.statusMessage,
code: response.statusMessage === 'invalid-api-key' ? 401 : 400,
};
if (response.headers) {
error_1[globalTransactionId] = response.headers[globalTransactionId];
}
cb(error_1, null);
return;
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.';
}
// If we have a response and it contains an error
if (body && (body.error || body.error_code)) {
// visual recognition sets body.error to a json object with code/description/error_id instead of putting them top-left
if (typeof body.error === 'object' && body.error.description) {
var errObj = body.error; // just in case there's a body.error.error...
Object.keys(body.error).forEach(function (key) {
body[key] = body.error[key];
});
Object.keys(body.error).forEach(function (key) {
body[key] = body.error[key];
});
body.error = errObj.description;
}
else if (typeof body.error === 'object' && typeof body.error.error === 'object') {
// this can happen with, for example, the conversation createSynonym() API
body.rawError = body.error;
body.error = JSON.stringify(body.error.error); //
}
// language translaton returns json with error_code and error_message
error = new Error(body.error || body.error_message || 'Error Code: ' + body.error_code);
error.code = body.error_code;
Object.keys(body).forEach(function (key) {
error[key] = body[key];
});
body = null;
}
// If we still don't have an error and there was an error...
if (!error && (response.statusCode < 200 || response.statusCode >= 300)) {
// The JSON stringify for the error below is for the Dialog service
// It stringifies "[object Object]" into the correct error (PR #445)
error = new Error(typeof body === 'object' ? JSON.stringify(body) : body);
error.code = response.statusCode;
body = null;
}
// ensure a more descriptive error message
if (error && (error.code === 401 || error.code === 403)) {
error.body = error.message;
error.message = 'Unauthorized: Access is denied due to invalid credentials.';
}
if (error && response && response.headers) {
error[globalTransactionId] = response.headers[globalTransactionId];
}
cb(error, body, response);
return;
};
}
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.formatErrorIfExists = formatErrorIfExists;
exports.formatError = formatError;
/**

@@ -144,23 +132,6 @@ * Creates the request.

function sendRequest(parameters, _callback) {
var missingParams = null;
var options = extend(true, {}, parameters.defaultOptions, parameters.options);
var path = options.path, body = options.body, form = options.form, formData = options.formData, qs = options.qs;
// Missing parameters
if (parameters.options.requiredParams) {
// eslint-disable-next-line no-console
console.warn(new Error('requiredParams set on parameters.options - it should be set directly on parameters'));
}
missingParams = helper_1.getMissingParams(parameters.originalParams || extend({}, qs, body, form, formData, path), parameters.requiredParams);
if (missingParams) {
if (typeof _callback === 'function') {
return _callback(missingParams);
}
else {
var errorStream_1 = new stream_1.PassThrough();
setTimeout(function () {
errorStream_1.emit('error', missingParams);
}, 0);
return errorStream_1;
}
}
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

@@ -173,42 +144,86 @@ if (formData) {

Object.keys(formData).forEach(function (key) {
// tslint:disable-next-line:no-unused-expression
(formData[key] == null ||
if (formData[key] == null ||
helper_1.isEmptyObject(formData[key]) ||
(formData[key].hasOwnProperty('contentType') && !formData[key].hasOwnProperty('data'))) &&
(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) { return formData[key].data != null && (formData[key] = helper_1.buildRequestFileObject(formData[key])); });
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) { return Array.isArray(formData[key]) && (formData[key] = formData[key].join(',')); });
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) {
return !helper_1.isFileParam(formData[key]) &&
if (!helper_1.isFileParam(formData[key]) &&
!Array.isArray(formData[key]) &&
typeof formData[key] === 'object' &&
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
options.url = parsePath(options.url, path);
delete options.path;
url = parsePath(url, path);
// Headers
options.headers = extend({}, options.headers);
// Query params
if (options.qs && Object.keys(options.qs).length > 0) {
// dialog doesn't like qs params joined with a `,`
if (!parameters.defaultOptions.url.match(/dialog\/api/)) {
Object.keys(options.qs).forEach(function (key) { return Array.isArray(options.qs[key]) && (options.qs[key] = options.qs[key].join(',')); });
}
options.useQuerystring = true;
// 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 (options.url.charAt(0) === '/') {
options.url = parameters.defaultOptions.url + options.url;
if (url && url.charAt(0) === '/') {
url = parameters.defaultOptions.url + url;
}
// Compression support
options.gzip = true;
return request(options, formatErrorIfExists(_callback));
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());
}
// 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(requestParams)
.then(function (res) {
// 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.0.1",
"version": "0.0.2",
"description": "Core functionality to support SDKs generated with IBM's OpenAPI 3 SDK Generator.",

@@ -5,0 +5,0 @@ "main": "./index",

# node-sdk-core
This project contains the core functionality used by Node SDK's generated by the IBM OpenAPI 3 SDK Generator (openapi-sdkgen).
Code generated by openapi-sdkgen will depend on the function contained in this project.
This project contains the core functionality used by Node SDK's generated by the IBM OpenAPI 3 SDK Generator (`openapi-sdkgen`).
Code generated by `openapi-sdkgen` will depend on the functionality contained in this project.
## Installation
`npm install ibm-cloud-sdk-core`
## Usage
This package exports a single object containing a number of modules as top level properties.
Example:
```js
// do some stuff
// this is TypeScript, since the `openapi-sdkgen` project generates TypeScript
import { BaseService } from 'ibm-cloud-sdk-core';
class YourSDK extends BaseService { ... }
```
## Available Modules
### BaseService
This Class is the base class that all generated service-specific classes inherit from. It implements credentials handling and other shared behavior.
### IamTokenManagerV1
This Class contains logic for managing an IAM token over its lifetime. Tokens can be requested or set manually. When requested, the token manager will either return the current token, request a new token or refresh the current token if it is expired. If a token is manually set, it must be managed by the user.
### isFileParam
This function takes an Object and returns `true` if the object is a Stream, a Buffer, has a `value` property, or has a `data` property that is a file param (checked recursively).
### isEmptyObject
This function takes an Object and returns `true` if it is an empty object.
### getContentType
This function attempts to retrieve the content type of the input and returns `null` if not found.
### stripTrailingSlash
This function takes a string and returns an identical string but with a forward slash removed from the end, if present.
### getMissingParams
This function takes in a list of required parameters and a parameters object and returns `null` if all required parameters are present and an Error if any are missing.
### isHTML
This function returns `true` if the given string is HTML.
### getFormat
This function takes a parameters object and a list of "formats". It returns the first match from the formats array that is a key in the parameters object, or `null` if there are no matches.
### buildRequestFileObject
This function builds a "form-data" object for each file parameter.
### toLowerKeys
This function takes an Object and returns the same object with all of the top-level keys converted to lower case. Note: it does not convert nested keys.
### qs
This module includes one function, `stringify`.
#### qs.stringify
This function takes an Object containing query parameters and returns a URI-encoded query String. This function is modified for use with Watson - the query parameter `watson-token` will not be encoded, as the server requires non-encoded tokens for authentication.
### contentType
This module includes two functions, `fromHeader` and `fromFilename`.
#### contentType.fromHeader
This function attempts to use the first bytes of a file to match the file contents with the associated mime type. Returns `undefined` if no matching mime type is found.
#### contentType.fromFilename
This function attempts to parse the extension from a file and return the mime type associated with the file contents. Returns `undefined` if no matching mime type is found.
### streamToPromise
This function takes a Stream and converts it to a Promise that resolves with the final text, encoded with `utf-8`.

@@ -60,19 +60,5 @@ {

"./lib/*.ts",
"./conversation/*.ts",
"./assistant/*.ts",
"./natural-language-classifier/*.ts",
"./language-translator/*.ts",
"./discovery/*.ts",
"./natural-language-understanding/*.ts",
"./visual-recognition/*.ts",
"./personality-insights/*.ts",
"./tone-analyzer/*.ts",
"./text-to-speech/*.ts",
"./speech-to-text/*.ts",
"./authorization/*.ts",
"./iam-token-manager/*.ts",
"./dialog/*.ts",
"./compare-comply/*.ts",
"index.ts"
]
}

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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc