spotify-finder
Advanced tools
Comparing version 1.0.0 to 2.0.0
@@ -1,72 +0,282 @@ | ||
var request = require('superagent') | ||
var qs = require('querystring') | ||
'use strict' | ||
function Client (options) { | ||
this.options = options || {} | ||
this.endpoint = this.options.endpoint || 'https://api.spotify.com/v1' | ||
} | ||
const request = require('request-promise') | ||
const Promise = require('bluebird') | ||
const qs = require('querystring') | ||
const localStorageExp = require('./localStorageExp') | ||
Client.prototype._request = function (path, params, callback) { | ||
var url = this.endpoint + path | ||
class Client { | ||
/** | ||
* @param {Object} [opts] - Setup custom's endpoints | ||
*/ | ||
constructor (opts) { | ||
this.baseURL = opts && opts.url ? opts.url : 'https://api.spotify.com/v1' | ||
this.authURL = opts && opts.auth ? opts.auth : 'https://accounts.spotify.com/api/token' | ||
this.consumer = opts && opts.consumer ? opts.consumer : null | ||
this.endpoints = { | ||
search: `${this.baseURL}/search`, | ||
albums: `${this.baseURL}/albums`, | ||
artists: `${this.baseURL}/artists`, | ||
tracks: `${this.baseURL}/tracks`, | ||
browse: `${this.baseURL}/browse`, | ||
auth: this.authURL | ||
} | ||
} | ||
/* istanbul ignore else */ | ||
if (params) url = url + '?' + qs.encode(params) | ||
/** | ||
* @param {string} path - endpoint to send request | ||
* @param {Object} [params] - querystrings | ||
*/ | ||
fetch (path, params) { | ||
path = params ? `${path}?${qs.encode(params)}` : path | ||
request | ||
.get(url) | ||
.set('Accept', 'application/json') | ||
.end(function (err, res) { | ||
if (err || !res.ok) return callback('An error ocurred in the request ' + err) | ||
const opts = { | ||
method: 'GET', | ||
uri: path, | ||
json: true | ||
} | ||
callback(null, res.body) | ||
}) | ||
} | ||
return request(opts) | ||
} | ||
Client.prototype.search = function (q, type, limit, callback) { | ||
/* istanbul ignore else */ | ||
if (type === 'all') type = 'artist,album,track' | ||
/** | ||
* @param {string} path - endpoint to send request | ||
* @param {Object} [params] - querystrings | ||
*/ | ||
fetchOAuth (path, params) { | ||
path = params ? `${path}?${qs.encode(params)}` : path | ||
this._request('/search', { q, type, limit }, callback) | ||
} | ||
return Promise.resolve(this.getToken().then((token) => { | ||
const opts = { | ||
method: 'GET', | ||
uri: path, | ||
headers: { | ||
'Authorization': `Bearer ${token}` | ||
}, | ||
json: true | ||
} | ||
Client.prototype.getAlbum = function (id, options, callback) { | ||
var url = '/albums/' + id | ||
return request(opts) | ||
})) | ||
} | ||
/* istanbul ignore else */ | ||
if (options.tracks) url += '/tracks' | ||
getToken () { | ||
/* istanbul ignore else */ | ||
if (!this.consumer) { | ||
return Promise.reject('Client credentials are not provided') | ||
} | ||
this._request(url, null, callback) | ||
} | ||
const key = this.consumer.key | ||
const secret = this.consumer.secret | ||
const encode = new Buffer(`${key}:${secret}`).toString('base64') | ||
Client.prototype.getAlbums = function (array_ids, callback) { | ||
var ids = array_ids.toString() | ||
this._request('/albums', { ids }, callback) | ||
} | ||
const opts = { | ||
method: 'POST', | ||
url: this.endpoints.auth, | ||
form: { | ||
grant_type: 'client_credentials' | ||
}, | ||
headers: { | ||
'Authorization': `Basic ${encode}` | ||
}, | ||
json: true | ||
} | ||
Client.prototype.getArtist = function (id, options, region, callback) { | ||
var url = '/artists/' + id | ||
var country = region || 'SE' | ||
const token = localStorageExp.load('token') | ||
/* istanbul ignore else */ | ||
if (token) { | ||
return Promise.resolve(token) | ||
} | ||
if (options.albums) url += '/albums' | ||
else if (options.topTracks) url += '/top-tracks' | ||
else if (options.relatedArtists) url += '/related-artists' | ||
return Promise.resolve( | ||
request(opts).then((data) => { | ||
localStorageExp.save('token', data.access_token, 50) | ||
return data.access_token | ||
}) | ||
) | ||
} | ||
this._request(url, { country }, callback) | ||
} | ||
/** | ||
* @param {Object} params - Options for the find | ||
* @param {string} params.q - Query for the find | ||
* @param {string} [params.type='artist,albums,track'] - Type of find | ||
* @param {string} [params.limit=20] - Limit of find | ||
* @param {requestCallback} [callback] -The callback that handles the response | ||
*/ | ||
search (params, callback) { | ||
/* istanbul ignore else */ | ||
if (params) { | ||
params.type = !params.type ? 'artist,album,track' : params.type | ||
} | ||
Client.prototype.getArtists = function (array_ids, callback) { | ||
var ids = array_ids.toString() | ||
this._request('/artists', { ids }, callback) | ||
} | ||
if (callback) { | ||
return Promise | ||
.resolve(this.fetch(this.endpoints.search, params)) | ||
.asCallback(callback) | ||
} | ||
Client.prototype.getTrack = function (id, callback) { | ||
var url = '/tracks/' + id | ||
this._request(url, null, callback) | ||
} | ||
return Promise.resolve(this.fetch(this.endpoints.search, params)) | ||
} | ||
Client.prototype.getTracks = function (array_ids, callback) { | ||
var ids = array_ids.toString() | ||
this._request('/tracks', { ids }, callback) | ||
/** | ||
* @param {string} id - id of an album spotify | ||
* @param {Object} [opts] - Options for the find | ||
* @param {Boolean} [opts.tracks=false] - get only tracks | ||
* @param {requestCallback} [callback] -The callback that handles the response | ||
*/ | ||
getAlbum (id, opts, callback) { | ||
let url = `${this.endpoints.albums}/${id}` | ||
url = opts && opts.tracks ? `${url}/tracks` : url | ||
/* istanbul ignore else */ | ||
if (callback) { | ||
return Promise | ||
.resolve(this.fetch(url)) | ||
.asCallback(callback) | ||
} | ||
return Promise.resolve(this.fetch(url)) | ||
} | ||
/** | ||
* @param {Array} array_ids - ids of albums spotify | ||
* @param {requestCallback} [callback] -The callback that handles the response | ||
*/ | ||
getAlbums (array_ids, callback) { | ||
const ids = array_ids.toString() | ||
/* istanbul ignore else */ | ||
if (callback) { | ||
return Promise | ||
.resolve(this.fetch(this.endpoints.albums, { ids })) | ||
.asCallback(callback) | ||
} | ||
return Promise.resolve(this.fetch(this.endpoints.albums, { ids })) | ||
} | ||
/** | ||
* @param {string} id - id of an artists spotify | ||
* @param {Object} [opts] - Options for the find | ||
* @param {string} [opts.country] - country market | ||
* @param {Boolean} [opts.albums] - get only albums of artist | ||
* @param {Boolean} [opts.topTracks] - get only top-tracks of artist | ||
* @param {Boolean} [opts.relatedArtists] - get only related-artists of artist | ||
*/ | ||
getArtist (id, opts, callback) { | ||
let url = `${this.endpoints.artists}/${id}` | ||
const country = opts && opts.country ? opts.country : 'SE' | ||
if (opts && opts.albums) url += '/albums' | ||
else if (opts && opts.topTracks) url += '/top-tracks' | ||
else if (opts && opts.relatedArtists) url += '/related-artists' | ||
/* istanbul ignore else */ | ||
if (callback) { | ||
return Promise | ||
.resolve(this.fetch(url, { country })) | ||
.asCallback(callback) | ||
} | ||
return Promise.resolve(this.fetch(url, { country })) | ||
} | ||
/** | ||
* @param {Array} array_ids - ids of artists spotify | ||
* @param {requestCallback} [callback] -The callback that handles the response | ||
*/ | ||
getArtists (array_ids, callback) { | ||
const ids = array_ids.toString() | ||
/* istanbul ignore else */ | ||
if (callback) { | ||
return Promise | ||
.resolve(this.fetch(this.endpoints.artists, { ids })) | ||
.asCallback(callback) | ||
} | ||
return Promise.resolve(this.fetch(this.endpoints.artists, { ids })) | ||
} | ||
/** | ||
* @param {string} id - id of a track spotify | ||
* @param {requestCallback} [callback] -The callback that handles the response | ||
*/ | ||
getTrack (id, callback) { | ||
const url = `${this.endpoints.tracks}/${id}` | ||
/* istanbul ignore else */ | ||
if (callback) { | ||
return Promise | ||
.resolve(this.fetch(url)) | ||
.asCallback(callback) | ||
} | ||
return Promise.resolve(this.fetch(url)) | ||
} | ||
/** | ||
* @param {Array} array_ids - ids of tracks spotify | ||
* @param {requestCallback} [callback] -The callback that handles the response | ||
*/ | ||
getTracks (array_ids, callback) { | ||
const ids = array_ids.toString() | ||
/* istanbul ignore else */ | ||
if (callback) { | ||
return Promise | ||
.resolve(this.fetch(this.endpoints.tracks, { ids })) | ||
.asCallback(callback) | ||
} | ||
return Promise.resolve(this.fetch(this.endpoints.tracks, { ids })) | ||
} | ||
/** | ||
* @param {Object} params - query parameters | ||
* @param {Object} params.to - navigate to where | ||
* @param {requestCallback} [callback] -The callback that handles the response | ||
*/ | ||
browse (params, callback) { | ||
const permitted = ['featured-playlists', 'new-releases', 'categories'] | ||
const index = permitted.indexOf(params.to) | ||
let url = this.endpoints.browse | ||
/* istanbul ignore else */ | ||
if (index >= 0) { | ||
url += `/${permitted[index]}` | ||
} | ||
delete params.to | ||
/* istanbul ignore else */ | ||
if (callback) { | ||
return Promise | ||
.resolve(this.fetchOAuth(url, params)) | ||
.asCallback(callback) | ||
} | ||
return Promise.resolve(this.fetchOAuth(url, params)) | ||
} | ||
/** | ||
* @param {string} id - id of an category spotify | ||
* @param {Object} [opts] - options for request | ||
* @param {requestCallback} [callback] -The callback that handles the response | ||
*/ | ||
getCategory (id, opts, callback) { | ||
let url = `${this.endpoints.browse}/categories/${id}` | ||
url = opts && opts.playlists ? `${url}/playlists` : url | ||
/* istanbul ignore else */ | ||
if (callback) { | ||
return Promise | ||
.resolve(this.fetchOAuth(url)) | ||
.asCallback(callback) | ||
} | ||
return Promise.resolve(this.fetchOAuth(url)) | ||
} | ||
} | ||
module.exports = Client |
@@ -1,17 +0,18 @@ | ||
{ | ||
"name": "spotify-finder", | ||
"version": "1.0.0", | ||
"description": "A Spotify API Client", | ||
"main": "index.js", | ||
"version": "2.0.0", | ||
"description": "A isomorphic Spotify API client", | ||
"main": "lib/index.js", | ||
"scripts": { | ||
"lint": "standard", | ||
"coverage": "istanbul cover tape -- test/*-test.js", | ||
"test": "npm run lint && tape test/*-test.js | tap-spec" | ||
"coverage": "istanbul cover tape -- test/test.js test/oauth-test.js test/*-test.js", | ||
"pretest": "rm -rf store", | ||
"test": "npm run lint && tape test/test.js test/oauth-test.js test/*-test.js | tap-spec", | ||
"posttest": "rm -rf store" | ||
}, | ||
"repository": { | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/luixlacrux/spotify-finder.git" | ||
}, | ||
"bugs": { | ||
"bugs": { | ||
"url": "https://github.com/luixlacrux/spotify-finder/issues" | ||
@@ -22,2 +23,3 @@ }, | ||
"devDependencies": { | ||
"coveralls": "^2.11.14", | ||
"istanbul": "^0.4.3", | ||
@@ -29,11 +31,15 @@ "nock": "^8.0.0", | ||
}, | ||
"keywords:": [ | ||
"keywords": [ | ||
"spotify", | ||
"spotify-api", | ||
"spotify-client" | ||
"spotify-client", | ||
"es6" | ||
], | ||
"homepage": "https://github.com/luixlacrux/spotify-finder#readme", | ||
"dependencies": { | ||
"superagent": "^1.8.3" | ||
"bluebird": "^3.4.6", | ||
"node-localstorage": "^1.3.0", | ||
"request": "^2.74.0", | ||
"request-promise": "^4.1.1" | ||
} | ||
} |
167
README.md
# spotify-finder | ||
[![Build Status](https://travis-ci.org/luixlacrux/spotify-finder.svg?branch=es6)](https://travis-ci.org/luixlacrux/spotify-finder) [![Coverage Status](https://coveralls.io/repos/github/luixlacrux/spotify-finder/badge.svg?branch=es6)](https://coveralls.io/github/luixlacrux/spotify-finder?branch=es6) | ||
--- | ||
A isomorphic Spotify client, that use the [Client Credentials](https://developer.spotify.com/web-api/authorization-guide/#client_credentials_flow) authorization flow. It allows to use some [Spotify Web API](https://developer.spotify.com/web-api/) endpoints. | ||
A Spotify Client for Node.js (non promised) | ||
It allows to use some [Spotify Web API](https://developer.spotify.com/web-api/) endpoints | ||
## Install | ||
@@ -12,38 +12,72 @@ ``` | ||
``` js | ||
var spotify = require('spotify-finder') | ||
var client = spotify.createClient() | ||
```js | ||
import Spotify from 'spotify-finder' | ||
const client = new Spotify({ | ||
consumer: { | ||
key: 'YOUR_CLIENT_ID', // if your not have an app in spotify ignore this options | ||
secret: 'YOUR_CLIENT_SECRET' // if your not have an app in spotify ignore this options | ||
} | ||
}) | ||
``` | ||
Note: if you do not Provide the client credentials, some features that require authentication will not be available. | ||
To create an application in Spotify. [click here](https://developer.spotify.com/my-applications/#!/) | ||
#### Search for all types | ||
```js | ||
client.search('Demi', 'all', 10, function (err, data) { | ||
// do something with data | ||
}) | ||
const params = { | ||
q: 'Demi', // required | ||
} | ||
client.search(params) | ||
.then(data => { | ||
// do something with data | ||
}) | ||
``` | ||
Parameter 'Demi' is search, 'all' type of search '10' limit of results. | ||
##### types alowed: | ||
* artists | ||
* albums | ||
* tracks | ||
* all | ||
#### Search for type specific with limit | ||
```js | ||
const params = { | ||
q: 'Stone Cold', // required | ||
type: 'artist', // optional for default 'artist,album,track' | ||
limit: 5 // optional for default 20 | ||
} | ||
client.search(params) | ||
.then(data => { | ||
// do something with data | ||
}) | ||
``` | ||
#### Search for type specific | ||
#### Get a List of New Releases | ||
```js | ||
client.search('Stone Cold', 'track', 2, function (err, tracks) { | ||
// do something with tracks | ||
}) | ||
client.browse({ to: 'new-releases' }) | ||
.then(albums => { | ||
// do something with album's | ||
}) | ||
``` | ||
#### Get a List of Featured Playlists | ||
```js | ||
client.browse({ to: 'featured-playlists' }) | ||
.then(playlists => { | ||
// do something with playlist's | ||
}) | ||
``` | ||
#### Get a List of Categories | ||
```js | ||
client.browse({ to: 'categories' } | ||
.then(categories => { | ||
// do something with categories | ||
}) | ||
``` | ||
#### Get album by id | ||
```js | ||
client.getAlbum('41MnTivkwTO3UUJ8DrqEJJ', { tracks: false }, function (err, album) { | ||
// do something with album | ||
}) | ||
client.getAlbum('41MnTivkwTO3UUJ8DrqEJJ', { tracks: false }) | ||
.then(album => { | ||
// do something with album | ||
}) | ||
``` | ||
#### Get an album's tracks | ||
```js | ||
client.getAlbum('41MnTivkwTO3UUJ8DrqEJJ', { tracks: true }, function (err, tracks) { | ||
// do something with tracks | ||
}) | ||
client.getAlbum('41MnTivkwTO3UUJ8DrqEJJ', { tracks: true }) | ||
.then(tracks => { | ||
// do something with tracks | ||
}) | ||
``` | ||
@@ -53,5 +87,7 @@ | ||
```js | ||
client.getAlbums(['41MnTivkwTO3UUJ8DrqEJJ', '6UXCm6bOO4gFlDQZV5yL37'], function (err, albums) { | ||
// do something with albums | ||
}) | ||
const ids = ['41MnTivkwTO3UUJ8DrqEJJ', '6UXCm6bOO4gFlDQZV5yL37'] | ||
client.getAlbums(ids) | ||
.then(albums => { | ||
// do something with albums | ||
}) | ||
``` | ||
@@ -61,5 +97,6 @@ | ||
```js | ||
client.getArtist('6S2OmqARrzebs0tKUEyXyp', {}, function (err, artist) { | ||
// do something with artist | ||
}) | ||
client.getArtist('6S2OmqARrzebs0tKUEyXyp') | ||
.then(artist => { | ||
// do something with artist | ||
}) | ||
``` | ||
@@ -69,5 +106,6 @@ | ||
```js | ||
client.getArtist('6S2OmqARrzebs0tKUEyXyp', { albums: true }, null, function (err, albums) { | ||
// do something with albums | ||
}) | ||
client.getArtist('6S2OmqARrzebs0tKUEyXyp', { albums: true }) | ||
.then(albums => { | ||
// do something with albums | ||
}) | ||
``` | ||
@@ -77,5 +115,6 @@ | ||
```js | ||
client.getArtist('6S2OmqARrzebs0tKUEyXyp', { topTracks: true }, null, function (err, tracks) { | ||
// do something with tracks | ||
}) | ||
client.getArtist('6S2OmqARrzebs0tKUEyXyp', { topTracks: true }) | ||
.then(tracks => { | ||
// do something with tracks | ||
}) | ||
``` | ||
@@ -85,5 +124,6 @@ | ||
```js | ||
client.getArtist('6S2OmqARrzebs0tKUEyXyp', { relatedArtists: true }, null, function (err, artists) { | ||
//do something with artists | ||
}) | ||
client.getArtist('6S2OmqARrzebs0tKUEyXyp', { relatedArtists: true }) | ||
.then(artists => { | ||
//do something with artists | ||
}) | ||
``` | ||
@@ -93,5 +133,7 @@ | ||
```js | ||
client.getArtists(['15deb326635d69d0505434', '934da7155ec15deb32663'], function (err, artists) { | ||
//do something with artists | ||
}) | ||
const ids = ['15deb326635d69d0505434', '934da7155ec15deb32663'], | ||
client.getArtists(ids) | ||
.then(artists => { | ||
//do something with artists | ||
}) | ||
``` | ||
@@ -101,5 +143,6 @@ | ||
```js | ||
client.getTrack('934da7155ec15deb32663', function (err, track) { | ||
//do something with track | ||
}) | ||
client.getTrack('934da7155ec15deb32663') | ||
.then(track => { | ||
//do something with track | ||
}) | ||
``` | ||
@@ -109,29 +152,7 @@ | ||
```js | ||
client.getTracks(['15deb326635d69d0505s', 'da7155ec15deb326635d69d'], function (err, tracks) { | ||
//do something with tracks | ||
}) | ||
const ids = ['15deb326635d69d0505s', 'da7155ec15deb326635d69d'] | ||
client.getTracks(ids) | ||
.then(tracks => { | ||
//do something with tracks | ||
}) | ||
``` | ||
## License MIT | ||
Copyright (c) 2016 - Luis Lacruz | ||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
The above copyright notice and this permission notice shall be included in | ||
all copies or substantial portions of the Software. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. |
Sorry, the diff of this file is not supported yet
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
30247
16
726
150
4
6
1
+ Addedbluebird@^3.4.6
+ Addednode-localstorage@^1.3.0
+ Addedrequest@^2.74.0
+ Addedrequest-promise@^4.1.1
+ 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.12.0(transitive)
+ Addedbcrypt-pbkdf@1.0.2(transitive)
+ Addedbluebird@3.7.2(transitive)
+ Addedcaseless@0.12.0(transitive)
+ Addedcore-util-is@1.0.2(transitive)
+ Addeddashdash@1.14.1(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)
+ Addedgraceful-fs@4.2.11(transitive)
+ Addedhar-schema@2.0.0(transitive)
+ Addedhar-validator@5.1.5(transitive)
+ Addedhttp-signature@1.2.0(transitive)
+ Addedimurmurhash@0.1.4(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)
+ Addedjson-stringify-safe@5.0.1(transitive)
+ Addedjsprim@1.4.2(transitive)
+ Addedlodash@4.17.21(transitive)
+ Addednode-localstorage@1.3.1(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)
+ Addedrequest-promise@4.2.6(transitive)
+ Addedrequest-promise-core@1.1.4(transitive)
+ Addedsafe-buffer@5.2.1(transitive)
+ Addedsafer-buffer@2.1.2(transitive)
+ Addedslide@1.1.6(transitive)
+ Addedsshpk@1.18.0(transitive)
+ Addedstealthy-require@1.1.1(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)
+ Addedwrite-file-atomic@1.3.4(transitive)
- Removedsuperagent@^1.8.3
- Removedasync@1.5.2(transitive)
- Removedcomponent-emitter@1.2.1(transitive)
- Removedcookiejar@2.0.6(transitive)
- Removedcore-util-is@1.0.3(transitive)
- Removeddebug@2.6.9(transitive)
- Removedextend@3.0.0(transitive)
- Removedform-data@1.0.0-rc3(transitive)
- Removedformidable@1.0.17(transitive)
- Removedinherits@2.0.4(transitive)
- Removedisarray@0.0.1(transitive)
- Removedmethods@1.1.2(transitive)
- Removedmime@1.3.4(transitive)
- Removedms@2.0.0(transitive)
- Removedqs@2.3.3(transitive)
- Removedreadable-stream@1.0.27-1(transitive)
- Removedreduce-component@1.0.1(transitive)
- Removedstring_decoder@0.10.31(transitive)
- Removedsuperagent@1.8.5(transitive)