Comparing version 2.0.0 to 3.0.0
21
index.js
@@ -1,16 +0,5 @@ | ||
/* | ||
* Copyright 2014 Wit.AI Inc. All rights reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
module.exports = require("./lib/wit.js"); | ||
module.exports = { | ||
Logger: require('./lib/logger.js').Logger, | ||
logLevels: require('./lib/logger.js').logLevels, | ||
Wit: require('./lib/wit.js').Wit, | ||
} |
334
lib/wit.js
@@ -1,97 +0,269 @@ | ||
/* | ||
* Copyright 2014 Wit.AI Inc. All rights reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
'use strict'; | ||
var request = require('request'); | ||
var _ = require('underscore'); | ||
var VERSION = "20150306"; | ||
const request = require('request'); | ||
const readline = require('readline'); | ||
const rl = readline.createInterface({ | ||
input: process.stdin, | ||
output: process.stdout, | ||
}); | ||
const uuid = require('node-uuid'); | ||
const Logger = require('./logger').Logger; | ||
const logLevels = require('./logger').logLevels; | ||
var getHeaders = function (access_token, others) { | ||
return _.extend(others || {}, { | ||
'Authorization': 'Bearer ' + access_token, | ||
'Accept': 'application/vnd.wit.' + VERSION | ||
}); | ||
}; | ||
const DEFAULT_MAX_STEPS = 5; | ||
const CALLBACK_TIMEOUT_MS = 10000; | ||
/** | ||
* Returns the meaning extracted from the text input | ||
* @param access_token your access token from your instance settings page | ||
* @param text the text you want to analyze | ||
* @param [options] json object to be passed to wit. Can include any of 'context', 'verbose', 'n' | ||
* @param callback callback that takes 2 arguments err and the response body | ||
*/ | ||
var captureTextIntent = function (access_token, text, options, callback) { | ||
if(!callback) { | ||
callback = options; | ||
options = undefined; | ||
let l = new Logger(logLevels.LOG); | ||
const makeWitResponseHandler = (endpoint, l, cb) => ( | ||
(error, response, data) => { | ||
const err = error || | ||
data.error || | ||
response.statusCode !== 200 && data.body + ' (' + response.statusCode + ')' | ||
; | ||
if (err) { | ||
l.error('[' + endpoint + '] Error: ' + err); | ||
if (cb) { | ||
cb(err); | ||
} | ||
return; | ||
} | ||
l.debug('[' + endpoint + '] Response: ' + JSON.stringify(data)); | ||
if (cb) { | ||
cb(null, data); | ||
} | ||
} | ||
); | ||
// Set up the query | ||
query_params = _.extend({'q': text}, options); | ||
const validateActions = (actions) => { | ||
const learnMore = 'Learn more at https://wit.ai/docs/quickstart'; | ||
if (typeof actions !== 'object') { | ||
throw new Error('The second parameter should be an Object.'); | ||
} | ||
if (!actions.say) { | ||
throw new Error('The \'say\' action is missing. '); | ||
} | ||
if (!actions.merge) { | ||
throw new Error('The \'merge\' action is missing. ' + learnMore); | ||
} | ||
Object.keys(actions).forEach(key => { | ||
if (typeof actions[key] !== 'function') { | ||
throw new Error('The \'' + key + '\' action should be a function.'); | ||
} | ||
if (key === 'say' && actions.say.length !== 3) { | ||
throw new Error('The \'say\' action should accept 3 arguments: sessionId, message, callback. ' + learnMore); | ||
} else if (key === 'merge' && actions.merge.length !== 3) { | ||
throw new Error('The \'merge\' action should accept 3 arguments: context, entities, callback. ' + learnMore); | ||
} else if (key !== 'say' && key !== 'merge' && actions[key].length !== 2) { | ||
throw new Error('The \'' + key + '\' action should accept 2 arguments: context, callback. ' + learnMore); | ||
} | ||
}); | ||
return actions; | ||
}; | ||
// Request options | ||
var request_options = { | ||
url: 'https://api.wit.ai/message', | ||
qs: query_params, | ||
json: true, | ||
headers: getHeaders(access_token) | ||
const makeCallbackTimeout = (ms) => { | ||
return setTimeout(() => { | ||
l.warn('I didn\'t get the callback after ' + (ms / 1000) + ' seconds. Did you forget to call me back?'); | ||
}, ms); | ||
}; | ||
const Wit = function(token, actions, logger) { | ||
this.req = request.defaults({ | ||
baseUrl: process.env.WIT_URL || 'https://api.wit.ai', | ||
strictSSL: false, | ||
json: true, | ||
headers: { | ||
'Authorization': 'Bearer ' + token, | ||
}, | ||
}); | ||
if (logger) { | ||
l = logger; | ||
} | ||
this.actions = validateActions(actions); | ||
this.message = (message, cb) => { | ||
const options = { | ||
uri: '/message', | ||
method: 'GET', | ||
qs: { q: message }, | ||
}; | ||
this.req(options, makeWitResponseHandler('message', l, cb)); | ||
}; | ||
// Make the request | ||
request(request_options, function (error, response, body) { | ||
if (response && response.statusCode != 200) { | ||
error = "Invalid response received from server: " + response.statusCode | ||
this.converse = (sessionId, message, context, cb) => { | ||
const options = { | ||
uri: '/converse', | ||
method: 'POST', | ||
qs: { 'session_id': sessionId }, | ||
json: context, | ||
}; | ||
if (message) { | ||
options.qs.q = message; | ||
} | ||
this.req(options, makeWitResponseHandler('converse', l, cb)); | ||
}; | ||
const makeCallback = (i, sessionId, context, cb) => { | ||
return (error, json) => { | ||
let timeoutID; | ||
l.debug('Context: ' + JSON.stringify(context)); | ||
error = error || !json.type && 'Couldn\'t find type in Wit response'; | ||
if (error) { | ||
if (cb) { | ||
cb(error, context); | ||
} | ||
callback(error, body); | ||
}); | ||
}; | ||
return; | ||
} | ||
/** | ||
* Returns the meaning extracted from a audio stream | ||
* @param access_token your access token from your instance settings page | ||
* @param stream The audio stream to send over to WIT.AI | ||
* @param content_type The content-type for this audio stream (audio/wav, ...) | ||
* @param [options] json object to be passed to wit. Can include any of 'context', 'verbose', 'n' | ||
* @param callback callback that takes 2 arguments err and the response body | ||
*/ | ||
var captureSpeechIntent = function (access_token, stream, content_type, options, callback) { | ||
if(!callback) { | ||
callback = options; | ||
options = undefined; | ||
} | ||
// TODO(jodent) refactor | ||
if (json.type === 'stop') { | ||
// End of turn | ||
if (cb) { | ||
cb(null, context); | ||
} | ||
return; | ||
} else if (json.type === 'msg') { | ||
if (!this.actions.say) { | ||
if (cb) { | ||
cb('No \'say\' action found.'); | ||
} | ||
return; | ||
} | ||
timeoutID = makeCallbackTimeout(CALLBACK_TIMEOUT_MS); | ||
l.log('Executing say with message: ' + json.msg); | ||
this.actions.say(sessionId, json.msg, () => { | ||
if (timeoutID) { | ||
clearTimeout(timeoutID); | ||
timeoutID = null; | ||
} | ||
if (i <= 0) { | ||
l.warn('Max steps reached, halting.'); | ||
if (cb) { | ||
cb(null, context); | ||
} | ||
return; | ||
} | ||
// Set up the query (empty b/c not sending 'q') | ||
query_params = _.extend({}, options); | ||
// Retrieving action sequence | ||
this.converse( | ||
sessionId, | ||
null, | ||
context, | ||
makeCallback(--i, sessionId, context, cb).bind(this) | ||
); | ||
}); | ||
} else if (json.type === 'merge') { | ||
if (!this.actions.merge) { | ||
if (cb) { | ||
cb('No \'merge\' action found.'); | ||
} | ||
return; | ||
} | ||
l.log('Executing merge action'); | ||
timeoutID = makeCallbackTimeout(CALLBACK_TIMEOUT_MS); | ||
this.actions.merge(context, json.entities, (newContext) => { | ||
if (timeoutID) { | ||
clearTimeout(timeoutID); | ||
timeoutID = null; | ||
} | ||
const context = newContext || {}; | ||
l.debug('Context\': ' + JSON.stringify(context)); | ||
// Request options | ||
var request_options = { | ||
url: 'https://api.wit.ai/speech', | ||
qs: query_params, // may be empty object | ||
method: 'POST', | ||
json: true, | ||
headers: getHeaders(access_token, {'Content-Type': content_type}) | ||
if (i <= 0) { | ||
l.warn('Max steps reached, halting.'); | ||
if (cb) { | ||
cb(null, context); | ||
} | ||
return; | ||
} | ||
// Retrieving action sequence | ||
this.converse( | ||
sessionId, | ||
null, | ||
context, | ||
makeCallback(--i, sessionId, context, cb).bind(this) | ||
); | ||
}); | ||
} else if (json.type === 'action') { | ||
const action = json.action; | ||
if (!this.actions.hasOwnProperty(action)) { | ||
if (cb) { | ||
cb('No \'' + action + '\' action found.', context); | ||
} | ||
return; | ||
} | ||
// Context might be updated in action call | ||
l.log('Executing action: ' + action); | ||
timeoutID = makeCallbackTimeout(CALLBACK_TIMEOUT_MS); | ||
this.actions[action](context, (newContext) => { | ||
if (timeoutID) { | ||
clearTimeout(timeoutID); | ||
timeoutID = null; | ||
} | ||
const context = newContext || {}; | ||
l.debug('Context\': ' + JSON.stringify(context)); | ||
if (i <= 0) { | ||
l.warn('Max steps reached, halting.'); | ||
if (cb) { | ||
cb(null, context); | ||
} | ||
return; | ||
} | ||
// Retrieving action sequence | ||
this.converse( | ||
sessionId, | ||
null, | ||
context, | ||
makeCallback(--i, sessionId, context, cb).bind(this) | ||
); | ||
}); | ||
} else { // error | ||
l.log('Executing error action'); | ||
this.actions.error(sessionId, 'No action available.'); | ||
return; | ||
} | ||
}; | ||
}; | ||
// Pipe the request | ||
stream.pipe(request(request_options, function (error, response, body) { | ||
if (response && response.statusCode != 200) { | ||
error = "Invalid response received from server: " + response.statusCode | ||
} | ||
callback(error, body); | ||
})); | ||
this.runActions = (sessionId, message, context, cb, maxSteps) => { | ||
const steps = maxSteps ? maxSteps : DEFAULT_MAX_STEPS; | ||
this.converse( | ||
sessionId, | ||
message, | ||
context, | ||
makeCallback(steps, sessionId, context, cb).bind(this) | ||
); | ||
}; | ||
this.interactive = (initContext, maxSteps) => { | ||
const sessionId = uuid.v1(); | ||
const context = typeof initContext === 'object' ? initContext : {}; | ||
const steps = maxSteps ? maxSteps : DEFAULT_MAX_STEPS; | ||
rl.setPrompt('> '); | ||
rl.prompt(); | ||
rl.on('line', ((line) => { | ||
const msg = line.trim(); | ||
this.runActions( | ||
sessionId, | ||
msg, | ||
context, | ||
(error, context) => { | ||
if (error) { | ||
l.error(error); | ||
} | ||
rl.prompt(); | ||
}, | ||
steps | ||
); | ||
}).bind(this)); | ||
}; | ||
}; | ||
module.exports.captureTextIntent = captureTextIntent; | ||
module.exports.captureSpeechIntent = captureSpeechIntent; | ||
module.exports = { | ||
Wit: Wit, | ||
}; |
{ | ||
"name": "node-wit", | ||
"version": "2.0.0", | ||
"private": false, | ||
"homepage": "https://github.com/wit-ai/node-wit", | ||
"description": "Node module to request Wit.AI", | ||
"repository": "https://github.com/wit-ai/node-wit", | ||
"bugs": { | ||
"url": "https://github.com/wit-ai/node-wit/issues" | ||
}, | ||
"version": "3.0.0", | ||
"description": "Wit.ai Node.js SDK", | ||
"keywords": [ | ||
"wit", | ||
"automation", | ||
"home", | ||
"siri", | ||
"wit.ai", | ||
"bot", | ||
"botengine", | ||
"bots", | ||
"nlp", | ||
"speech", | ||
"intent", | ||
"jarvis" | ||
"automation" | ||
], | ||
"author": { | ||
"name": "Olivier Vaussy", | ||
"email": "oliv@wit.ai" | ||
}, | ||
"contributors": [ | ||
{ | ||
"name": "Anthony Kesich", | ||
"email": "anthony@wit.ai" | ||
}, | ||
{ | ||
"name": "irfaan", | ||
"email": "github@irfaan.com" | ||
} | ||
], | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "node_modules/mocha/bin/_mocha test/*_test.js --ignore-leaks -t 20000 --reporter spec" | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
}, | ||
"repository": "https://github.com/wit-ai/node-wit", | ||
"author": "Julien Odent <julien@wit.ai>", | ||
"dependencies": { | ||
"request": "2.42.0", | ||
"underscore": "1.7.0" | ||
}, | ||
"devDependencies": { | ||
"mocha": "1.21.4", | ||
"nock": "0.47.0", | ||
"chai": "1.9.1" | ||
}, | ||
"main": "./index.js" | ||
"node-uuid": "^1.4.7", | ||
"request": "^2.69.0" | ||
} | ||
} |
170
README.md
@@ -1,146 +0,50 @@ | ||
## Quick start | ||
# Wit Node.js SDK | ||
1. You need to create an [Wit instance first](https://wit.ai/docs/console/quickstart). | ||
`node-wit` is the Node.js SDK for [Wit.ai](https://wit.ai). | ||
2. Install [Node.JS](http://nodejs.org/) on your computer. | ||
## Install | ||
3. Setup your project | ||
In your Node.js project, run: | ||
Create a new Node.JS app : | ||
```bash | ||
$ mkdir myapp | ||
$ cd myapp | ||
$ npm init | ||
... | ||
``` | ||
Install and add node-wit as a dependencies in your package.json : | ||
```bash | ||
npm install --save node-wit | ||
``` | ||
Execute `npm install` in your current folder to fetch the dependencies | ||
We will send an audio file to Wit.AI | ||
You can use [SoX](http://sox.sourceforge.net) to record WAV files from the command line. | ||
`brew install sox` on OSX and `apt-get install sox` on ubuntu. | ||
The following options will create a Wit-ready WAV file (press Ctrl+C to stop recording): | ||
```bash | ||
sox -d -b 16 -c 1 -r 16k sample.wav | ||
``` | ||
Create a `index.js` file in myapp directory containing: | ||
```javascript | ||
var wit = require('node-wit'); | ||
var fs = require('fs'); | ||
var ACCESS_TOKEN = "IQ77NWUPUMNBYEUEKRTWU3VDR5YSLHTA"; | ||
console.log("Sending text & audio to Wit.AI"); | ||
wit.captureTextIntent(ACCESS_TOKEN, "Hello world", function (err, res) { | ||
console.log("Response from Wit for text input: "); | ||
if (err) console.log("Error: ", err); | ||
console.log(JSON.stringify(res, null, " ")); | ||
}); | ||
var stream = fs.createReadStream('sample.wav'); | ||
wit.captureSpeechIntent(ACCESS_TOKEN, stream, "audio/wav", function (err, res) { | ||
console.log("Response from Wit for audio stream: "); | ||
if (err) console.log("Error: ", err); | ||
console.log(JSON.stringify(res, null, " ")); | ||
}); | ||
``` | ||
4. Start your app | ||
```bash | ||
$ node index.js | ||
Sending text & audio to Wit.AI | ||
Response from Wit for text input: | ||
{ | ||
"msg_id": "b46d4a08-1e2e-43f4-b30a-aaa7bccb88e3", | ||
"_text": "Hello world", | ||
"outcomes": [ | ||
{ | ||
"_text": "Hello world", | ||
"intent": "greetings_hi", | ||
"entities": {}, | ||
"confidence": 0.929 | ||
} | ||
] | ||
} | ||
Response from Wit for audio stream: | ||
{ | ||
"msg_id": "83c14e47-13cb-4ad4-9f5e-723cd47016be", | ||
"_text": "what's the weather in New York", | ||
"outcomes": [ | ||
{ | ||
"_text": "what's the weather in New York", | ||
"intent": "weather", | ||
"entities": { | ||
"location": [ | ||
{ | ||
"suggested": true, | ||
"value": "New York" | ||
} | ||
] | ||
}, | ||
"confidence": 1 | ||
} | ||
] | ||
} | ||
npm install --save node-wit | ||
``` | ||
## Examples | ||
## Quickstart | ||
```nodejs | ||
'use strict'; | ||
const Wit = require('node-wit').Wit; | ||
## API | ||
const actions = { | ||
say: (sessionId, msg, cb) => { | ||
console.log(msg); | ||
cb(); | ||
}, | ||
merge: (context, entities, cb) => { | ||
cb(context); | ||
}, | ||
error: (sessionId, msg) => { | ||
console.log('Oops, I don\'t know what to do.'); | ||
}, | ||
'my-action': (context, cb) => { | ||
context['name'] = 'Julien'; | ||
cb(context); | ||
}, | ||
}; | ||
### captureTextIntent | ||
The `captureTextIntent` function returns the meaning extracted from the text | ||
input. The function takes 4 parameters: | ||
- `access_token`: Your access token for your instance | ||
- `text`: The text input you want to extract the meaning of | ||
- `options`: [optional] A json object containing any call options such as `verbose` or `context` | ||
- `callback(error, response)`: A callback function get 2 arguments: | ||
1. An `error` when applicable | ||
2. A JSON object containing the Wit.AI response | ||
```javascript | ||
var wit = require('node-wit'); | ||
wit.captureTextIntent(ACCESS_TOKEN, "Hello world", function (err, res) { | ||
console.log("Response from Wit for text input: "); | ||
if (err) console.log("Error: ", err); | ||
console.log(JSON.stringify(res, null, " ")); | ||
}); | ||
const client = new Wit('YOUR_TOKEN', actions); | ||
client.interactive(); | ||
``` | ||
### captureSpeechIntent | ||
See `examples` folder for more examples. | ||
The `captureSpeechIntent` function returns the meaning extracted from the audio | ||
input. The function takes 5 arguments: | ||
- `access_token`: Your access token for your instance | ||
- `stream`: The audio stream you want to extract the meaning of | ||
- `content-type`: The content-type of your audio stream (`audio/wav`, `audio/mpeg3`, | ||
`audio/raw;encoding=unsigned-integer;bits=16;rate=8000;endian=big`, ...) | ||
- `options`: [optional] A json object containing any call options such as `verbose` or `context` | ||
- `callback(error, response)`: A callback function get 2 arguments: | ||
1. An `error` when applicable | ||
2. A JSON object containing the Wit.AI response | ||
```javascript | ||
var wit = require('node-wit'); | ||
var fs = require('fs'); | ||
var stream = fs.createReadStream('sample.wav'); | ||
wit.captureSpeechIntent(ACCESS_TOKEN, stream, "audio/wav", function (err, res) { | ||
console.log("Response from Wit for audio stream: "); | ||
if (err) console.log("Error: ", err); | ||
console.log(JSON.stringify(res, null, " ")); | ||
}); | ||
``` | ||
## API | ||
The Wit module provides a Wit class with the following methods: | ||
* `message` - the Wit message API | ||
* `converse` - the low-level Wit converse API | ||
* `runActions` - a higher-level method to the Wit converse API | ||
* `interactive` - starts an interactive conversation with your bot | ||
See the [docs](https://wit.ai/docs) for more information. |
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
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
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
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
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
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
0
2
384
2
13445
1
2
51
2
+ Addednode-uuid@^1.4.7
+ Addedajv@6.12.6(transitive)
+ Addedasn1@0.2.6(transitive)
+ Addedassert-plus@1.0.0(transitive)
+ Addedasynckit@0.4.0(transitive)
+ Addedaws-sign2@0.7.0(transitive)
+ Addedaws4@1.13.2(transitive)
+ Addedbcrypt-pbkdf@1.0.2(transitive)
+ Addedcaseless@0.12.0(transitive)
+ Addedcombined-stream@1.0.8(transitive)
+ Addedcore-util-is@1.0.2(transitive)
+ Addeddashdash@1.14.1(transitive)
+ Addeddelayed-stream@1.0.0(transitive)
+ Addedecc-jsbn@0.1.2(transitive)
+ Addedextend@3.0.2(transitive)
+ Addedextsprintf@1.3.0(transitive)
+ Addedfast-deep-equal@3.1.3(transitive)
+ Addedfast-json-stable-stringify@2.1.0(transitive)
+ Addedforever-agent@0.6.1(transitive)
+ Addedform-data@2.3.3(transitive)
+ Addedgetpass@0.1.7(transitive)
+ Addedhar-schema@2.0.0(transitive)
+ Addedhar-validator@5.1.5(transitive)
+ Addedhttp-signature@1.2.0(transitive)
+ Addedis-typedarray@1.0.0(transitive)
+ Addedisstream@0.1.2(transitive)
+ Addedjsbn@0.1.1(transitive)
+ Addedjson-schema@0.4.0(transitive)
+ Addedjson-schema-traverse@0.4.1(transitive)
+ Addedjsprim@1.4.2(transitive)
+ Addedmime-db@1.52.0(transitive)
+ Addedmime-types@2.1.35(transitive)
+ Addedoauth-sign@0.9.0(transitive)
+ Addedperformance-now@2.1.0(transitive)
+ Addedpsl@1.9.0(transitive)
+ Addedpunycode@2.3.1(transitive)
+ Addedqs@6.5.3(transitive)
+ Addedrequest@2.88.2(transitive)
+ Addedsafe-buffer@5.2.1(transitive)
+ Addedsafer-buffer@2.1.2(transitive)
+ Addedsshpk@1.18.0(transitive)
+ Addedtough-cookie@2.5.0(transitive)
+ Addedtunnel-agent@0.6.0(transitive)
+ Addedtweetnacl@0.14.5(transitive)
+ Addeduri-js@4.4.1(transitive)
+ Addeduuid@3.4.0(transitive)
+ Addedverror@1.10.0(transitive)
- Removedunderscore@1.7.0
- Removedasn1@0.1.11(transitive)
- Removedassert-plus@0.1.5(transitive)
- Removedasync@0.9.2(transitive)
- Removedaws-sign2@0.5.0(transitive)
- Removedbl@0.9.5(transitive)
- Removedboom@0.4.2(transitive)
- Removedcaseless@0.6.0(transitive)
- Removedcombined-stream@0.0.7(transitive)
- Removedcore-util-is@1.0.3(transitive)
- Removedcryptiles@0.2.2(transitive)
- Removedctype@0.5.3(transitive)
- Removeddelayed-stream@0.0.5(transitive)
- Removedforever-agent@0.5.2(transitive)
- Removedform-data@0.1.4(transitive)
- Removedhawk@1.1.1(transitive)
- Removedhoek@0.9.1(transitive)
- Removedhttp-signature@0.10.1(transitive)
- Removedinherits@2.0.4(transitive)
- Removedisarray@0.0.1(transitive)
- Removedmime@1.2.11(transitive)
- Removedmime-types@1.0.2(transitive)
- Removedoauth-sign@0.4.0(transitive)
- Removedqs@1.2.2(transitive)
- Removedreadable-stream@1.0.34(transitive)
- Removedrequest@2.42.0(transitive)
- Removedsntp@0.2.4(transitive)
- Removedstring_decoder@0.10.31(transitive)
- Removedstringstream@0.0.6(transitive)
- Removedtldts@6.1.47(transitive)
- Removedtldts-core@6.1.47(transitive)
- Removedtough-cookie@5.0.0(transitive)
- Removedtunnel-agent@0.4.3(transitive)
- Removedunderscore@1.7.0(transitive)
Updatedrequest@^2.69.0