botkit-middleware-watson
Advanced tools
Comparing version 1.8.4 to 2.0.0
@@ -5,3 +5,2 @@ { | ||
"packages": [ | ||
"examples/multi-bot/package.json", | ||
"examples/simple-bot/package.json", | ||
@@ -8,0 +7,0 @@ "package.json" |
{ | ||
"name": "botkit-middleware-watson", | ||
"version": "1.8.4", | ||
"version": "2.0.0", | ||
"description": "A middleware for using Watson Assistant in a Botkit-powered bot.", | ||
"main": "lib/middleware/index.js", | ||
"types": "lib/middleware/index.d.ts", | ||
"main": "lib/index.js", | ||
"types": "lib/index.d.ts", | ||
"scripts": { | ||
"start": "node lib/middleware/index.js", | ||
"test": "mocha test", | ||
"lint": "eslint ." | ||
"build": "node ./node_modules/typescript/bin/tsc", | ||
"pretest": "npm run build", | ||
"test": "jest test --coverage --forceExit", | ||
"lint": "npm run build && eslint '*/**/*.ts' --quiet --fix", | ||
"version": "npm run build && git add -A lib", | ||
"precommit": "lint-staged" | ||
}, | ||
@@ -27,17 +30,45 @@ "repository": { | ||
"devDependencies": { | ||
"assert": "^1.4.1", | ||
"botkit": "^0.7.2", | ||
"@types/jest": "^24.0.12", | ||
"@types/nock": "^10.0.1", | ||
"@types/sinon": "^7.0.11", | ||
"@typescript-eslint/eslint-plugin": "^1.7.0", | ||
"@typescript-eslint/parser": "^1.7.0", | ||
"botbuilder-adapter-web": "^1.0.1", | ||
"botkit": "^4.0.1", | ||
"clone": "^2.1.2", | ||
"eslint": "^5.9.0", | ||
"mocha": "^6.0.0", | ||
"nock": "^10.0.2", | ||
"sinon": "^7.1.1" | ||
"codecov": "^3.3.0", | ||
"eslint": "^5.16.0", | ||
"eslint-config-prettier": "^4.2.0", | ||
"eslint-plugin-prettier": "^3.0.1", | ||
"husky": "^2.2.0", | ||
"jest": "^24.8.0", | ||
"lint-staged": "^8.1.5", | ||
"nock": "^10.0.6", | ||
"prettier": "^1.17.0", | ||
"sinon": "^7.3.2", | ||
"ts-jest": "^24.0.2", | ||
"typescript": "^3.4.5" | ||
}, | ||
"prettier": { | ||
"printWidth": 80, | ||
"singleQuote": true, | ||
"trailingComma": "all" | ||
}, | ||
"dependencies": { | ||
"@types/bluebird": "^3.5.24", | ||
"bluebird": "^3.5.3", | ||
"debug": "^4.1.0", | ||
"debug": "^4.1.1", | ||
"deepmerge": "^3.2.0", | ||
"watson-developer-cloud": "^3.13.0" | ||
"ibm-watson": "^4.1.0" | ||
}, | ||
"lint-staged": { | ||
"src/**/*.ts": [ | ||
"npm run build", | ||
"npm run lint", | ||
"git add" | ||
] | ||
}, | ||
"husky": { | ||
"hooks": { | ||
"pre-commit": "lint-staged" | ||
} | ||
} | ||
} |
311
README.md
@@ -5,2 +5,27 @@ # Use IBM Watson's Assistant service to chat with your Botkit-powered Bot! [![Build Status](https://travis-ci.org/watson-developer-cloud/botkit-middleware.svg?branch=master)](https://travis-ci.org/watson-developer-cloud/botkit-middleware) [![Greenkeeper badge](https://badges.greenkeeper.io/watson-developer-cloud/botkit-middleware.svg)](https://greenkeeper.io/) | ||
<details> | ||
<summary>Table of Contents</summary> | ||
* [Middleware Overview](#middleware-overview) | ||
* [Function Overview](#function-overview) | ||
* [Installation](#installation) | ||
* [Prerequisites](#prerequisites) | ||
+ [Acquire channel credentials](#acquire-channel-credentials) | ||
+ [Bot setup](#bot-setup) | ||
* [Features](#features) | ||
+ [Message filtering](#message-filtering) | ||
- [Using interpret function instead of registering middleware](#using-interpret-function-instead-of-registering-middleware) | ||
- [Using middleware wrapper](#using-middleware-wrapper) | ||
+ [Minimum Confidence](#minimum-confidence) | ||
- [Use it manually in your self-defined controller.hears() function(s)](#use-it-manually-in-your-self-defined-controllerhears-functions) | ||
- [Use the middleware's hear() function](#use-the-middlewares-hear-function) | ||
+ [Implementing app actions](#implementing-app-actions) | ||
+ [Using sendToWatson to update context](#using-sendtowatson-to-update-context) | ||
* [Implementing event handlers](#implementing-event-handlers) | ||
+ [Intent matching](#intent-matching) | ||
- [`before` and `after`](#before-and-after) | ||
- [Dynamic workspace](#dynamic-workspace) | ||
</details> | ||
## Middleware Overview | ||
@@ -29,3 +54,3 @@ | ||
```sh | ||
$ npm install botkit-middleware-watson --save | ||
$ npm install botkit-middleware-watson | ||
``` | ||
@@ -35,5 +60,5 @@ | ||
1. Sign up for an [IBM Cloud account](https://console.bluemix.net/registration/). | ||
1. Sign up for an [IBM Cloud account](https://cloud.ibm.com/registration/). | ||
1. Create an instance of the Watson Assistant service and get your credentials: | ||
- Go to the [Watson Assistant](https://console.bluemix.net/catalog/services/conversation) page in the IBM Cloud Catalog. | ||
- Go to the [Watson Assistant](https://cloud.ibm.com/catalog/services/conversation) page in the IBM Cloud Catalog. | ||
- Log in to your IBM Cloud account. | ||
@@ -44,13 +69,8 @@ - Click **Create**. | ||
1. Create a workspace using the Watson Assistant service and copy the `workspace_id`. If you don't know how to create a workspace follow the [Getting Started tutorial](https://console.bluemix.net/docs/services/conversation/getting-started.html). | ||
1. Create a workspace using the Watson Assistant service and copy the `workspace_id`. If you don't know how to create a workspace follow the [Getting Started tutorial](https://cloud.ibm.com/docs/services/conversation/getting-started.html). | ||
### Acquire channel credentials | ||
This document shows code snippets for using a Slack bot with the middleware. (If you want examples for the other channels, see the [examples/multi-bot](/examples/multi-bot) folder. | ||
The multi-bot example app shows how to connect to Slack, Facebook, and Twilio IPM bots running on a single Express server.) | ||
This document shows code snippets for using a Slack bot with the middleware. You need a _Slack token_ for your Slack bot to talk to Watson Assistant. If you have an existing Slack bot, then copy the Slack token from your Slack settings page. | ||
You need a _Slack token_ for your Slack bot to talk to Watson Assistant. | ||
If you have an existing Slack bot, then copy the Slack token from your Slack settings page. | ||
Otherwise, follow [Botkit's instructions](https://botkit.ai/docs/provisioning/slack-events-api.html) to create your Slack bot from scratch. When your bot is ready, you are provided with a Slack token. | ||
@@ -64,12 +84,19 @@ | ||
```js | ||
const slackController = Botkit.slackbot({ clientSigningSecret: YOUR_SLACK_SIGNING_SECRET }); | ||
``` | ||
import { WatsonMiddleware } from 'botkit-middleware-watson'; | ||
import Botkit = require('botkit'); | ||
const { SlackAdapter } = require('botbuilder-adapter-slack'); | ||
Spawn a Slack bot using the controller: | ||
```js | ||
const slackBot = slackController.spawn({ | ||
token: YOUR_SLACK_TOKEN | ||
const adapter = new SlackAdapter({ | ||
clientSigningSecret: process.env.SLACK_SECRET, | ||
botToken: process.env.SLACK_TOKEN | ||
}); | ||
const controller = new Botkit({ | ||
adapter, | ||
// ...other options | ||
}); | ||
``` | ||
Create the middleware object which you'll use to connect to the Watson Assistant service. | ||
@@ -80,3 +107,3 @@ | ||
```js | ||
const watsonMiddleware = require('botkit-middleware-watson')({ | ||
const watsonMiddleware = new WatsonMiddleware({ | ||
username: YOUR_ASSISTANT_USERNAME, | ||
@@ -94,3 +121,3 @@ password: YOUR_ASSISTANT_PASSWORD, | ||
```js | ||
const watsonMiddleware = require('botkit-middleware-watson')({ | ||
const watsonMiddleware = new WatsonMiddleware({ | ||
iam_apikey: YOUR_API_KEY, | ||
@@ -106,4 +133,3 @@ url: YOUR_ASSISTANT_URL, | ||
```js | ||
slackController.middleware.receive.use(watsonMiddleware.receive); | ||
slackBot.startRTM(); | ||
controller.middleware.receive.use(watsonMiddleware.receive.bind(watsonMiddleware)); | ||
``` | ||
@@ -113,7 +139,7 @@ | ||
```js | ||
slackController.hears(['.*'], ['direct_message', 'direct_mention', 'mention'], function(bot, message) { | ||
controller.hears(['.*'], ['direct_message', 'direct_mention', 'mention'], async function(bot, message) { | ||
if (message.watsonError) { | ||
bot.reply(message, "I'm sorry, but for technical reasons I can't respond to your message"); | ||
await bot.reply(message, "I'm sorry, but for technical reasons I can't respond to your message"); | ||
} else { | ||
bot.reply(message, message.watsonData.output.text.join('\n')); | ||
await bot.reply(message, message.watsonData.output.text.join('\n')); | ||
} | ||
@@ -137,10 +163,9 @@ }); | ||
```js | ||
slackController.hears(['.*'], ['direct_message'], function(bot, message) { | ||
middleware.interpret(bot, message, function() { | ||
if (message.watsonError) { | ||
bot.reply(message, "I'm sorry, but for technical reasons I can't respond to your message"); | ||
} else { | ||
bot.reply(message, message.watsonData.output.text.join('\n')); | ||
} | ||
}); | ||
slackController.hears(['.*'], ['direct_message'], async (bot, message) => { | ||
await middleware.interpret(bot, message) | ||
if (message.watsonError) { | ||
bot.reply(message, "I'm sorry, but for technical reasons I can't respond to your message"); | ||
} else { | ||
bot.reply(message, message.watsonData.output.text.join('\n')); | ||
} | ||
}); | ||
@@ -152,3 +177,3 @@ ``` | ||
```js | ||
const receiveMiddleware = function (bot, message, next) { | ||
const receiveMiddleware = (bot, message, next) => { | ||
if (message.type === 'direct_message') { | ||
@@ -172,12 +197,12 @@ watsonMiddleware.receive(bot, message, next); | ||
```js | ||
controller.hears(['.*'], ['direct_message', 'direct_mention', 'mention', 'message_received'], function(bot, message) { | ||
controller.hears(['.*'], ['direct_message', 'direct_mention', 'mention', 'message_received'], async (bot, message) => { | ||
if (message.watsonError) { | ||
bot.reply(message, "Sorry, there are technical problems."); // deal with watson error | ||
await bot.reply(message, "Sorry, there are technical problems."); // deal with watson error | ||
} else { | ||
if (message.watsonData.intents.length == 0) { | ||
bot.reply(message, "Sorry, I could not understand the message."); // was any intent recognized? | ||
await bot.reply(message, "Sorry, I could not understand the message."); // was any intent recognized? | ||
} else if (message.watsonData.intents[0].confidence < watsonMiddleware.minimum_confidence) { | ||
bot.reply(message, "Sorry, I am not sure what you have said."); // is the confidence high enough? | ||
await bot.reply(message, "Sorry, I am not sure what you have said."); // is the confidence high enough? | ||
} else { | ||
bot.reply(message, message.watsonData.output.text.join('\n')); // reply with Watson response | ||
await bot.reply(message, message.watsonData.output.text.join('\n')); // reply with Watson response | ||
} | ||
@@ -189,2 +214,3 @@ } | ||
#### Use the middleware's hear() function | ||
You can find the default implementation of this function [here](https://github.com/watson-developer-cloud/botkit-middleware/blob/e29b002f2a004f6df57ddf240a3fdf8cb28f95d0/lib/middleware/index.js#L40). If you want, you can redefine this function in the same way that watsonMiddleware.before and watsonMiddleware.after can be redefined. Refer to the [Botkit Middleware documentation](https://botkit.ai/docs/core.html#controllerhears) for an example. Then, to use this function instead of Botkit's default pattern matcher (that does not use minimum_confidence), plug it in using: | ||
@@ -199,3 +225,3 @@ ```js | ||
Watson Assistant side of app action is documented in [Developer Cloud](https://console.bluemix.net/docs/services/assistant/deploy-custom-app.html#deploy-custom-app) | ||
Watson Assistant side of app action is documented in [Developer Cloud](https://cloud.ibm.com/docs/services/assistant/deploy-custom-app.html#deploy-custom-app) | ||
A common scenario of processing actions is: | ||
@@ -209,8 +235,8 @@ | ||
### using sendToWatson to update context (possible since v1.5.0) | ||
### Using sendToWatson to update context | ||
Using sendToWatson to update context simplifies the bot code compared to solution using updateContext below. | ||
```js | ||
function checkBalance(context, callback) { | ||
const checkBalance = async (context) => { | ||
//do something real here | ||
@@ -221,14 +247,12 @@ const contextDelta = { | ||
}; | ||
callback(null, context); | ||
} | ||
return context; | ||
}); | ||
const checkBalanceAsync = Promise.promisify(checkBalance); | ||
const processWatsonResponse = function (bot, message) { | ||
const processWatsonResponse = async (bot, message) => { | ||
if (message.watsonError) { | ||
return bot.reply(message, "I'm sorry, but for technical reasons I can't respond to your message"); | ||
return await bot.reply(message, "I'm sorry, but for technical reasons I can't respond to your message"); | ||
} | ||
if (typeof message.watsonData.output !== 'undefined') { | ||
//send "Please wait" to users | ||
bot.reply(message, message.watsonData.output.text.join('\n')); | ||
await bot.reply(message, message.watsonData.output.text.join('\n')); | ||
@@ -239,9 +263,9 @@ if (message.watsonData.output.action === 'check_balance') { | ||
checkBalanceAsync(message.watsonData.context).then(function (contextDelta) { | ||
return watsonMiddleware.sendToWatsonAsync(bot, newMessage, contextDelta); | ||
}).catch(function (error) { | ||
try { | ||
const contextDelta = await checkBalance(message.watsonData.context); | ||
await watsonMiddleware.sendToWatson(bot, newMessage, contextDelta); | ||
} catch(error) { | ||
newMessage.watsonError = error; | ||
}).then(function () { | ||
return processWatsonResponse(bot, newMessage); | ||
}); | ||
} | ||
return await processWatsonResponse(bot, newMessage); | ||
} | ||
@@ -254,97 +278,2 @@ } | ||
#### Using updateContext in controller (available since v1.4.0) | ||
Since 1.4.0 it is possible to update context from controller code. | ||
```js | ||
function checkBalance(context, callback) { | ||
//this version of function updates only the context object | ||
context.validAccount = true; | ||
context.accountBalance = 95.33; | ||
callback(null, context); | ||
} | ||
const checkBalanceAsync = Promise.promisify(checkBalance); | ||
const processWatsonResponse = function (bot, message) { | ||
if (message.watsonError) { | ||
return bot.reply(message, "I'm sorry, but for technical reasons I can't respond to your message"); | ||
} | ||
if (typeof message.watsonData.output !== 'undefined') { | ||
//send "Please wait" to users | ||
bot.reply(message, message.watsonData.output.text.join('\n')); | ||
if (message.watsonData.output.action === 'check_balance') { | ||
const newMessage = clone(message); | ||
newMessage.text = 'balance result'; | ||
//check balance | ||
checkBalanceAsync(message.watsonData.context).then(function (context) { | ||
//update context in storage | ||
return watsonMiddleware.updateContextAsync(message.user, context); | ||
}).then(function () { | ||
//send message to watson (it reads updated context from storage) | ||
return watsonMiddleware.sendToWatsonAsync(bot, newMessage); | ||
}).catch(function (error) { | ||
newMessage.watsonError = error; | ||
}).then(function () { | ||
//send results to user | ||
return processWatsonResponse(bot, newMessage); | ||
}); | ||
} | ||
} | ||
}; | ||
controller.on('message_received', processWatsonResponse); | ||
``` | ||
#### Using middleware.after and controller | ||
Before v1.4.0 only middleware.after callback can update context, and only controller can send replies to user. | ||
The downside is that it is impossible to send "Please wait message". | ||
```js | ||
function checkBalance(watsonResponse, callback) { | ||
//middleware.after function must pass a complete Watson respose to callback | ||
watsonResponse.context.validAccount = true; | ||
watsonResponse.context.accountBalance = 95.33; | ||
callback(null, watsonResponse); | ||
} | ||
watsonMiddleware.after = function(message, watsonResponse, callback) { | ||
//real action happens in middleware.after | ||
if (typeof watsonResponse !== 'undefined' && typeof watsonResponse.output !== 'undefined') { | ||
if (watsonResponse.output.action === 'check_balance') { | ||
return checkBalance(watsonResponse, callback); | ||
} | ||
} | ||
callback(null, watsonResponse); | ||
}; | ||
const processWatsonResponse = function(bot, message) { | ||
if (message.watsonError) { | ||
return bot.reply(message, "I'm sorry, but for technical reasons I can't respond to your message"); | ||
} | ||
if (typeof message.watsonData.output !== 'undefined') { | ||
//send "Please wait" to users | ||
bot.reply(message, message.watsonData.output.text.join('\n')); | ||
if (message.watsonData.output.action === 'check_balance') { | ||
const newMessage = clone(message); | ||
newMessage.text = 'balance result'; | ||
//send to watson | ||
watsonMiddleware.interpret(bot, newMessage, function() { | ||
//send results to user | ||
processWatsonResponse(bot, newMessage); | ||
}); | ||
} | ||
} | ||
}; | ||
controller.on('message_received', processWatsonResponse); | ||
``` | ||
## Implementing event handlers | ||
@@ -354,30 +283,21 @@ | ||
[Example](https://github.com/howdyai/botkit/blob/master/examples/facebook_bot.js) of handler: | ||
[Example](https://github.com/howdyai/botkit/blob/master/packages/docs/reference/facebook.md#facebookeventtypemiddleware) of handler: | ||
```js | ||
controller.on('facebook_postback', function(bot, message) { | ||
bot.reply(message, 'Great Choice!!!! (' + message.payload + ')'); | ||
controller.on('facebook_postback', async (bot, message) => { | ||
await bot.reply(message, `Great Choice. (${message.payload})`); | ||
}); | ||
``` | ||
Since they usually have no text, events aren't processed by middleware and have no watsonData attribute. | ||
If event handler wants to make use of some data from context, it has to read it first. | ||
Example: | ||
```js | ||
controller.on('facebook_postback', function(bot, message) { | ||
watsonMiddleware.readContext(message.user, function(err, context) { | ||
if (!context) { | ||
context = {}; | ||
} | ||
controller.on('facebook_postback', async (bot, message) => { | ||
const context = watsonMiddleware.readContext(message.user); | ||
//do something useful here | ||
myFunction(context.field1, context.field2, function(err, result) { | ||
const newMessage = clone(message); | ||
newMessage.text = 'postback result'; | ||
watsonMiddleware.sendToWatson(bot, newMessage, {postbackResult: 'success'}, function(err) { | ||
if (err) { | ||
newMessage.watsonError = error; | ||
} | ||
processWatsonResponse(bot, newMessage); | ||
}); | ||
}); | ||
}); | ||
const result = await myFunction(context.field1, context.field2); | ||
const newMessage = {...message, text: 'postback result' }; | ||
await watsonMiddleware.sendToWatson(bot, newMessage, { postbackResult: 'success' }); | ||
}); | ||
@@ -399,4 +319,4 @@ ``` | ||
```js | ||
slackController.hears(['hello'], ['direct_message', 'direct_mention', 'mention'], watsonMiddleware.hear, function(bot, message) { | ||
bot.reply(message, message.watsonData.output.text.join('\n')); | ||
slackController.hears(['hello'], ['direct_message', 'direct_mention', 'mention'], watsonMiddleware.hear, async function(bot, message) { | ||
await bot.reply(message, message.watsonData.output.text.join('\n')); | ||
// now do something special related to the hello intent | ||
@@ -409,6 +329,6 @@ }); | ||
```js | ||
slackController.changeEars(watsonMiddleware.hear); | ||
slackController.changeEars(watsonMiddleware.hear.bind(watsonMiddleware)); | ||
slackController.hears(['hello'], ['direct_message', 'direct_mention', 'mention'], function(bot, message) { | ||
bot.reply(message, message.watsonData.output.text.join('\n')); | ||
slackController.hears(['hello'], ['direct_message', 'direct_mention', 'mention'], async (bot, message) => { | ||
await bot.reply(message, message.watsonData.output.text.join('\n')); | ||
// now do something special related to the hello intent | ||
@@ -420,3 +340,3 @@ }); | ||
The _before_ and _after_ callbacks can be used to perform some tasks _before_ and _after_ Assistant is called. One may use it to modify the request/response payloads, execute business logic like accessing a database or making calls to external services. | ||
The _before_ and _after_ async calls can be used to perform some tasks _before_ and _after_ Assistant is called. One may use it to modify the request/response payloads, execute business logic like accessing a database or making calls to external services. | ||
@@ -426,5 +346,5 @@ They can be customized as follows: | ||
```js | ||
middleware.before = function(message, assistantPayload, callback) { | ||
// Code here gets executed before making the call to Assistant. | ||
callback(null, customizedPayload); | ||
middleware.before = (message, assistantPayload) => async () => { | ||
// Code here gets executed before making the call to Assistant. | ||
return assistantPayload; | ||
} | ||
@@ -434,6 +354,6 @@ ``` | ||
```js | ||
middleware.after = function(message, assistantResponse, callback) { | ||
// Code here gets executed after the call to Assistant. | ||
callback(null, assistantResponse); | ||
} | ||
middleware.after = (message, assistantResponse) => async () => { | ||
// Code here gets executed after the call to Assistant. | ||
return assistantResponse; | ||
}); | ||
``` | ||
@@ -443,19 +363,20 @@ | ||
If you need to make use of multiple workspaces in a single bot, workspace_id can be changed dynamically by setting workspace_id property in context. | ||
If you need to make use of multiple workspaces in a single bot, `workspace_id` can be changed dynamically by setting `workspace_id` property in context. | ||
Example of setting workspace_id to id provided as a property of hello message: | ||
Example of setting `workspace_id` to id provided as a property of hello message: | ||
```js | ||
function handleHelloEvent(bot, message) { | ||
message.type = 'welcome'; | ||
const contextDelta = {}; | ||
async handleHelloEvent = (bot, message) => { | ||
message.type = 'welcome'; | ||
const contextDelta = {}; | ||
if (message.workspaceId) { | ||
contextDelta.workspace_id = message.workspaceId; | ||
} | ||
if (message.workspaceId) { | ||
contextDelta.workspace_id = message.workspaceId; | ||
} | ||
watsonMiddleware.sendToWatsonAsync(bot, message, contextDelta).catch(function (error) { | ||
message.watsonError = error; | ||
}).then(function () { | ||
bot.reply(message, message.watsonData.output.text.join('\n')); | ||
}); | ||
try { | ||
await watsonMiddleware.sendToWatson(bot, message, contextDelta); | ||
} catch(error) { | ||
message.watsonError = error; | ||
} | ||
await bot.reply(message, message.watsonData.output.text.join('\n')); | ||
} | ||
@@ -462,0 +383,0 @@ |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
156133
3
29
960
20
23
365
1
+ Addedibm-watson@^4.1.0
+ Added@types/node@11.15.54(transitive)
+ Addedaxios@0.18.1(transitive)
+ Addedbuffer-equal-constant-time@1.0.1(transitive)
+ Addedecdsa-sig-formatter@1.0.11(transitive)
+ Addedfollow-redirects@1.5.10(transitive)
+ Addedform-data@2.5.2(transitive)
+ Addedibm-cloud-sdk-core@0.3.7(transitive)
+ Addedibm-watson@4.5.4(transitive)
+ Addedis-buffer@2.0.5(transitive)
+ Addedjsonwebtoken@8.5.1(transitive)
+ Addedjwa@1.4.1(transitive)
+ Addedjws@3.2.2(transitive)
+ Addedlodash.includes@4.3.0(transitive)
+ Addedlodash.isboolean@3.0.3(transitive)
+ Addedlodash.isinteger@4.0.4(transitive)
+ Addedlodash.isnumber@3.0.3(transitive)
+ Addedlodash.isplainobject@4.0.6(transitive)
+ Addedlodash.isstring@4.0.1(transitive)
+ Addedlodash.once@4.1.1(transitive)
+ Addedsemver@6.3.1(transitive)
- Removed@types/bluebird@^3.5.24
- Removedbluebird@^3.5.3
- Removedwatson-developer-cloud@^3.13.0
- Removed@types/bluebird@3.5.42(transitive)
- Removed@types/caseless@0.12.5(transitive)
- Removed@types/csv-stringify@1.4.3(transitive)
- Removed@types/form-data@2.5.2(transitive)
- Removed@types/request@2.47.1(transitive)
- Removed@types/tough-cookie@4.0.5(transitive)
- Removedajv@5.5.2(transitive)
- Removedasn1@0.2.6(transitive)
- Removedassert-plus@1.0.0(transitive)
- Removedaws-sign2@0.7.0(transitive)
- Removedaws4@1.13.2(transitive)
- Removedbcrypt-pbkdf@1.0.2(transitive)
- Removedbluebird@3.7.2(transitive)
- Removedbuffer-from@1.1.2(transitive)
- Removedcaseless@0.12.0(transitive)
- Removedco@4.6.0(transitive)
- Removedcore-util-is@1.0.2(transitive)
- Removedcsv-stringify@1.0.4(transitive)
- Removeddashdash@1.14.1(transitive)
- Removeddotenv@2.0.0(transitive)
- Removedecc-jsbn@0.1.2(transitive)
- Removedextsprintf@1.3.0(transitive)
- Removedfast-deep-equal@1.1.0(transitive)
- Removedfast-json-stable-stringify@2.1.0(transitive)
- Removedforever-agent@0.6.1(transitive)
- Removedform-data@2.3.34.0.1(transitive)
- Removedgetpass@0.1.7(transitive)
- Removedhar-schema@2.0.0(transitive)
- Removedhar-validator@5.0.3(transitive)
- Removedhttp-signature@1.2.0(transitive)
- Removedibm-cloud-sdk-core@0.0.3(transitive)
- Removedjsbn@0.1.1(transitive)
- Removedjson-schema@0.4.0(transitive)
- Removedjson-schema-traverse@0.3.1(transitive)
- Removedjson-stringify-safe@5.0.1(transitive)
- Removedjsprim@1.4.2(transitive)
- Removedlodash.get@4.4.2(transitive)
- Removedoauth-sign@0.8.2(transitive)
- Removedperformance-now@2.1.0(transitive)
- Removedpunycode@1.4.1(transitive)
- Removedqs@6.5.3(transitive)
- Removedrequest@2.87.0(transitive)
- Removedsafer-buffer@2.1.2(transitive)
- Removedsshpk@1.18.0(transitive)
- Removedtough-cookie@2.3.4(transitive)
- Removedtunnel-agent@0.6.0(transitive)
- Removedtweetnacl@0.14.5(transitive)
- Removeduuid@3.4.0(transitive)
- Removedverror@1.10.0(transitive)
- Removedwatson-developer-cloud@3.18.4(transitive)
Updateddebug@^4.1.1